学习作业2

问题1:主键都有哪些方式?

 

问题2:本次实战案例建立的主键采用哪种方式?

 

问题3:猜猜金蝶K3WISE建立的主键采用哪种方式?

 

问题4:谈谈手工主键增长设置具体实现思路?(选答)

 

问题5:GUID主键是啥玩意?(选答)

 

=============================================

=============================================

知识点:

1、创建主键的三种方法

方法一:

CREATE TABLE 学生

(

学号char(6) NOT NULL primary key ,

姓名char(8) NOT NULL ,

性别char(2) NOT NULL ,

出生日期smalldatetime NOT NULL ,

班级编号char(10) NOT NULL ,

学分numeric(8, 1) NOT NULL ,

区域char (4)  NOT NULL ,

校名char (24)  NOT NULL

)  ON [PRIMARY]

方法二:

CREATE TABLE 学生

(

学号char(6) NOT NULL ,

姓名char(8) NOT NULL ,

性别char(2) NOT NULL ,

出生日期smalldatetime NOT NULL ,

班级编号char(10) NOT NULL ,

学分numeric(8, 1) NOT NULL ,

区域char (4)  NOT NULL ,

校名char (24)  NOT NULL

CONSTRAINT PK_student_id  PRIMARY KEY  (学号)

) ON [PRIMARY] Go

方法三:(建完表再添加主键)

CREATE TABLE 学生

(

学号char(6) NOT NULL ,

姓名char(8) NOT NULL ,

性别char(2) NOT NULL ,

出生日期smalldatetime NOT NULL ,

班级编号char(10) NOT NULL ,

学分numeric(8, 1) NOT NULL ,

区域char (4)  NOT NULL ,

校名char (24)  NOT NULL

) ON [PRIMARY] go

alter table 学生 add

CONSTRAINT PK_student_id  PRIMARY KEY  (学号)

-- 联合主键 把两列设置成一个主键

CREATE TABLE book(

bid INT,

bname VARCHAR(100),

author VARCHAR(30),

CONSTRAINT pk_bid_bname PRIMARY KEY(bid,bname)

)

=============================================

=============================================

2、什么是主键?

一个表的主键是唯一标识,不能有重复,不允许为空。

举例1在数据表中,比如在学生表里面,把ID字段设为主键。

录入学生小林,ID为1436。再录入小张,ID为1437。

执行结果:由于小林和小张ID是不相同的,所以,都可以录入成功。

举例2现在,你再录入学生小黄,ID为1436,这时候会录入失败,产生消息预警提示。

执行结果:原因是ID作为主键,必须保证每一条记录的ID是唯一值,不能出现重复值。

因为小林和小黄的ID相同,导致后面录入的小黄就录入不成功。

====================================================

====================================================

3、什么是组合主键?

一个表的主键可以由一个字段或多个字段共同组成。

举例1在数据表中,比如在学生表里面,把ID、姓名设为组合主键。

录入学生小林,ID为1436。再录入小张,ID为1437。

执行结果:由于小林和小张ID、姓名都不相同,所以,都可以录入成功。

举例2现在,再录入学生小黄,ID为1436。

执行结果:由于小林和小黄虽然ID相同,但是他们姓名不同,没有构成唯一性重复的条件。

小黄也可以录入成功。(跟单个字段主键的区别是,单个字段主键是主键字段重复,就不可重复录入。组合主键,其中有一个字段重复,还是可以录入成功)

举例3现在,再录入学生小林,ID为1436。

执行结果:由于学生小林的ID和姓名都已存在,不可重复录入,录入失败。

4、SQL GUID和自增列做主键的优缺点

我们公司的数据库全部是使用GUID做主键的,很多人习惯使用int做主键。所以呢,这里总结一下,将两种数据类型做主键进行一个比较。

使用INT做主键的优点:

1、需要很小的数据存储空间,仅仅需要4 byte 。

2、insert和update操作时使用INT的性能比GUID好,所以使用int将会提高应用程序的性能。

3、index和Join 操作,int的性能最好。

4、容易记忆。

5、支持通过函数获取最新的值,如:Scope_Indentity() 。

使用INT做主键的缺点

1、如果经常有合并表的操作,就可能会出现主键重复的情况。

2、使用INT数据范围有限制。如果存在大量的数据,可能会超出INT的取值范围。(可以使用bigint)

3、很难处理分布式存储的数据表。

使用GUID做主键的优点:

1、它是独一无二的。

2、出现重复的机会少。

3、适合大量数据中的插入和更新操作。

4、跨服务器数据合并非常方便。

使用GUID做主键的缺点:

1、存储空间大(16 byte),因此它将会占用更多的磁盘大小。

2、很难记忆。join操作性能比int要低。

3、没有内置的函数获取最新产生的guid主键。

4、GUID做主键将会添加到表上的所有其他索引中,因此会降低性能。

总结:

上面列出了GUID和INT两种数据类型做主键优缺点。我觉得,对于大数据量,建议使用guid做主键。而使用int会得到最佳的性能。

5、浅析主键自增长的优缺点

主键应该怎样设计?目前主要用到的主键方案共三种

自动增长主键

手动增长主键

UNIQUEIDENTIFIER主键

1、先说自动增长主键,它的优点是简单,类型支持bigint.但是它有致命的弱点:

当我们需要在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制允许我们进行库间的数据复制操作),自动增长型字段可能造成数据合并时的主键冲突。设想一个数据库中的Order表向另一个库中的Order表复制数据库时,OrderID到底该不该自动增长呢?

2、再说手动增长主键,它的优点是自行定制主键列,主键列的数据类型乃至数据样本都可以控制,能够稳定的获得目标键值,不会重复.但是它维护成本比较搞,首先生成键值需要自行编写存储过程来产生,网络开销大,运行时还要考虑到并发冲突等等.

3、最后就是UNIQUEIDENTIFIER主键,它利用GUID作为键值,可以直接调用newid()来获得全局唯一标识,即便合并数据表也不会有重复现象.但是UGID有两个弱点:其一,和int类型比较,GUID长度是前者4倍.其二,用newid()获得的GUID毫无规律,因为该列作为主键,必然有聚集索引,那么在插入新数据时,将是一个非常耗时的操作.这样的话UNIQUEIDENTIFIER作为主键将大大有损效率.

所以SQLServer2000环境下DBA们往往写一个存储过程来生成与时间有关的GUID,即在GUID前面加上生成时间.这样确保生成出来的主键全局唯一并且按时间递增.不过这又回到了第二种主键方案,不便维护.

4、SQLServer 提供了新的解决方法,使用的是NEWSEQUENTIALID(),这个函数产生的GUID是递增的,下面看下它的用法

--创建实验表

--1创建id列的类型为UNIQUEIDENTIFIER

--2ROWGUIDCOL只是这个列的别名,一个表中只能有一个

--3PRIMARY KEY确定id为主键

--4使用DEFAULT约束来自动为该列添加GUID

create table jobs

(

id UNIQUEIDENTIFIER ROWGUIDCOL PRIMARY KEY  NOT NULL

CONSTRAINT [DF_jobs_id] DEFAULT (NEWSEQUENTIALID()),

account varchar(64) not null,

password varchar(64) not null

)

select * from jobs

--添加实验数据

insert jobs (account,password) values ('tudou','123')

insert jobs (account,password) values ('ntudou','123')

insert jobs (account,password) values ('atudou','123')

insert jobs (account,password) values ('btudou','123')

insert jobs (account,password) values ('ctudou','123')

select * from jobs

============================================

============================================

6、关于数据库设计中主键问题的思考

数据库主键在数据库中占有重要地位。主键的选取策略决定了系统是否可靠、易用、高效。本文探讨了数据库设计过程当中常见的主键选取策略,并剖析了其做主键的优缺点,提出了相应的解决问题的方法

在基于关系型数据库设计时候,通常要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行记录的属性或属性组,一个表只能有一个主键,但可以有多个候选索引。因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除、修改时不出现错误。当然,其它字段可以辅助我们在执行这些操作时消除共享冲突,不是本文讨论的重点,不再赘述。主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。所以数据库在设计时,主键起到了很重要的作用。常见的数据库主键选取方式有: 自动增长式、手动增长式 、UniqueIdentifier、联合式(复合式)、时间序列+随机数式、“COMB(Combine)”类型。

一、自动增长式

很多数据库设计者喜欢使用自动增长型字段,因为它使用简单。自动增长式允许我们在向数据库添加数据时,不考虑主键的取值,记录插入后,数据库系统会自动为其分配一个值,确保绝对不会出现重复。如果使用SQL Server数据库的话,我们还可以在记录插入后使用@@IDENTITY全局变量获取系统分配的主键值。
尽管自动增长式字段会省掉我们很多繁琐的工作,但使用它也存在潜在的问题,那就是在数据缓冲模式下,很难预先填写主键与外键的值。假设有主辅两张表:

Order(OrderID,
OrderDate) 订单表
OrderDetial(OrderID, LineNum, ProductID, Price) 订单明细表

Order 表中的OrderID是自动增长型的字段。假设现在需要我们录入一张订单,包括在Order表中插入一条记录以及在OrderDetail表中插入若干条记录。因为Order表中的OrderID是自动增长型的字段,那么我们在记录正式插入到数据库之前无法事先得知它的取值,只有在更新后才能知道数据库为它分配的是什么值。这会造成以下矛盾发生:
首先,为了能在OrderDetail的OrderID字段中添入正确的值,必须先更新 Order表以获取到系统为其分配的OrderID值,然后再用这个OrderID填充OrderDetail表的OrderID列。最后更新OderDetail表。但是,为了确保数据的一致性,Order与OrderDetail在更新时必须在事务模式下进行的,即要么两张表同时同时更新成功、要么全部失败,显然它们是相互矛盾的。
其次,当我们需要在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制允许我们进行库间的数据复制操作),自动增长式字段可能造成数据合并时的主键冲突及表关联关系的丢失。设想一个数据库中的Order表向另一个库中的Order表复制数据库时,OrderID到底该不该自动增长呢?如果自动增长,其子表OrderDetial的关联关系会丢失,如果不增长就会和现有数据主键重复,是不是很矛盾呢?
再次,自增量的值都是需要在系统中维护一个全局的数据值,每次插入数据时即对此次值进行增量取值。当在产生唯一标识的并发环境中,每次的增量取值都必须为此全局值加锁解锁以保证增量的唯一性。造成并发瓶颈,降低查询性能。
还有当数据表足够大或频繁的更改和插入操作导致主键类型值超出范围,这种情况一般很少碰到,但也是我们进行数据表设计时必须考虑的一个问题

二、手动增长型字段

既然自动增长型字段会带来如此的麻烦,我们不妨考虑使用手动增长型的字段,也就是说主键的值需要自己维护,通常情况下需要建立一张单独的表存储当前主键键值。为了叙述上的方便仍然利用上面的例子进行阐述,新建一张表叫IntKey,包含两个字段,KeyName以及KeyValue。就像一个HashTable,给一个KeyName,就可以知道目前的KeyValue是什么,然后手工实现键值数据递增。在SQL Server中可以编写这样一个存储过程,让取键值的过程自动进行。代码如下:

CREATE
PROCEDURE [GetKey]
@KeyName char(10),
@KeyValue int OUTPUT
AS
UPDATE IntKey SET @KeyValue = KeyValue = KeyValue + 1 WHERE KeyName = @KeyName
GO

这样,通过调用存储过程,我们可以获得最新键值,确保不会出现重复。若将OrderID字段设置为手动增长式字段,我们的程序可以由以下几步来实现:首先调用存储过程,获得一个OrderID,然后使用这个OrderID填充Order表与OrderDetail表,最后在事务机制下对两表进行更新。
使用手动增长式字段作为主键在进行数据库间数据复制时,可以确保数据合并过程中不会出现键值冲突,只要为不同的数据表分配不同的主键取值段就行了。但是,使用手动增长型字段会增加网络的负担,必须通过增加一次数据库访问来获取当前主键键值,这会增加网络和数据库的负载,当处于一个低速或断开的网络环境中时,这种做法会有很大的弊端。同时,手工维护主键还要考虑并发冲突等种种因素,这更会增加系统的复杂程度。

三、使用UniqueIdentifier

SQL Server为我们提供了UniqueIdentifier数据类型,并提供了一个生成函数NEWID( ),使用NEWID( )可以生成一个唯一的UniqueIdentifier。UniqueIdentifier在数据库中占用16个字节,出现重复的概率几乎为0,号称全球唯一标识。我们经常从注册表或WINDOWS程序出现错误需要调试时看到类似 768427bf-9b37-4776-97ca-000365e160d5或{45F0EB02-0727-4F2E-AAB5-E8AEDEE0CEC5}
的东西实际上就是一个UniqueIdentifier,Windows用它来做COM组件以及接口的标识,防止出现重复。在.NET中 UniqueIdentifier称之为GUID(Global Unique Identifier)。在C#中可以使用如下命令生成一个GUID:
Guid u = System.Guid.NewGuid();
对于上面提到的Order与OrderDetail的程序,如果选用UniqueIdentifier作为主键的话,我们完全可以避免上面提到的增加网络RoundTrip的问题。通过程序直接生成GUID填充主键,不用考虑是否会出现重复。 但是UniqueIdentifier 字段也存在严重的缺陷:首先,它的长度是16字节,是整数的4倍长,会占用大量存储空间。更为严重的是,UniqueIdentifier的生成毫无规律可言,也就是说是无序的,要想在上面建立索引(绝大多数数据库在主键上都有索引)是一个非常耗时的操作。有人做过实验,当数据表记录比较大的时,在不同的数据量级别上插入同样的数据量,使用 UniqueIdentifier型数据做主键要比使用Integer型数据慢,且还没有考虑到表关联的情况,出于效率考虑,尽可能避免使用UniqueIdentifier型数据库作为主键值,但随着现代计算机计算速度越来越快,在中小型项目中使用UniqueIdentifier式主键也是一个选项。

四、使用业务字段联合主键

基于DEPHI和POWERBUILDER等数据库工具开发C/S系统的数据库设计人员,习惯上用有业务意义的字段组合成复合主键做数据表主键。使用业务主键当然有其与生俱来的好处,一般情况下数据库系统会在默认条件下建立聚簇索引,而且这个聚簇索引基于主键升序排列,当数据量比较小时,我们感觉不到这种差别,当数据量比较大时,这种基于主键定义的聚簇索引的优势就显现出来,这就使得数据表在每次存取数据时按照索引准确确认数据插入或更新的磁盘物理位置,减少磁头寻址时间,从而提高数据库性能,而且能够从业务意义上保证数据的完整性,增加程序的可靠性。但是基于业务字段的联合索引,当业务字段选用比较多时会占用比较多的磁盘空间,而且索引页会占用更多的内存页面,从而导致查询命中率降低;另外使用业务主键,当涉及到主键数据的修改时,要在编程过程中记录新值和原值的关系表,在更新时又要进行新值和原值的比对,增加编写程序的复杂度。

五、时间序列+随机数主键

采用精确到毫秒甚至钠秒级的时间和一个随机产生的两位数做主键,如200911282311528+两位随机数,不失为解决主键问题的一个有效办法。这样产生的主键既避免了UniqueIdentifier型字段做主键时的无序,又能有效避免自动增长型主键带来的诸如复制和数据导入的麻烦。但在使用用户众多的网络实时系统中,在时间和空间上仍然不能保证唯一性的问题。

六、使用“COMB(Combine)”类型

既然上面五种主键类型选取策略都存在各自的缺点,那么到底有没有好的办法加以解决呢?答案是肯定的。通过使用COMB类型(数据库中没有COMB类型,它是Jimmy Nilsson在他的“The Cost of GUIDs as
Primary Keys”一文中设计出来的),可以在以上众多的主键策略之间采用中庸之道,找到一个很好的平衡点。

COMB数据类型的基本设计思路是这样的:既然UniqueIdentifier数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么我们能不能通过组合的方式,保留UniqueIdentifier的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与 UniqueIdentifier组合起来,在保留UniqueIdentifier的唯一性的同时增加了有序性,以此来提高索引效率。也许有人会担心 UniqueIdentifier减少到10字节会造成数据出现重复,其实不用担心,后6字节的时间精度可以达到1/300秒,两个COMB类型数据完全相同的可能性是在这1/300秒内生成的两个GUID前10个字节完全相同,这几乎是不可能的!在SQL Server中用SQL命令将这一思路实现出来便是:

DECLARE @aGuid
UNIQUEIDENTIFIER
SET @aGuid = CAST(CAST(NEWID() AS BINARY(10))
+ CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)

经过测试,使用COMB做主键比使用INT做主键,在检索、插入、更新、删除等操作上仍然显慢,但比Unidentifier类型要快上一些。除了使用存储过程实现COMB数据外,我们也可以使用C#生成COMB数据,这样所有主键生成工作可以在客户端完成。

C#代码如下:

复制代码 代码如下:

//================================================
/**////<summary>
/// 返回 GUID 用于数据库操作,特定的时间代码可以提高检索效率
/// </summary>
/// <returns>COMB (GUID 与时间混合型) 类型 GUID 数据</returns>
public static Guid NewComb()
{
byte[] guidArray = System.Guid.NewGuid().ToByteArray();
DateTime baseDate = new DateTime(1900,1,1);
DateTime now = DateTime.Now;
// Get the days and milliseconds which will be used to build the byte string
TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
TimeSpan msecs = new TimeSpan(now.Ticks - (new DateTime(now.Year, now.Month,
now.Day).Ticks));
// Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a millisecond so we divide by
3.333333
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray =
BitConverter.GetBytes((long)(msecs.TotalMilliseconds/3.333333));
// Reverse the bytes to match SQL Servers ordering
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
// Copy the bytes into the guid
Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6,
2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4,
4);
return new System.Guid(guidArray);
}
//================================================
/**//// <summary>
/// 从 SQL SERVER 返回的 GUID 中生成时间信息
/// </summary>
/// <param name="guid">包含时间信息的 COMB
</param>
/// <returns>时间</returns>
public static DateTime GetDateFromComb(System.Guid guid)
{
DateTime baseDate = new DateTime(1900,1,1);
byte[] daysArray = new byte[4];
byte[] msecsArray = new byte[4];
byte[] guidArray = guid.ToByteArray();
// Copy the date parts of the guid to the respective byte arrays.
Array.Copy(guidArray, guidArray.Length - 6, daysArray, 2, 2);
Array.Copy(guidArray, guidArray.Length - 4, msecsArray, 0, 4);
// Reverse the arrays to put them into the appropriate order
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
// Convert the bytes to ints
int days = BitConverter.ToInt32(daysArray, 0);
int msecs = BitConverter.ToInt32(msecsArray, 0);
DateTime date = baseDate.AddDays(days);
date = date.AddMilliseconds(msecs * 3.333333);
return date;
}

综上述六种主键选取策略,笔者认为使用“COMB(Combine)”类型做主键是比较恰当的主键应用策略,但在实际使用过程中要根据客观实践、因时因事选取适当的主键,切不可生搬硬套、弄巧成拙。

=============================================

=============================================

学习作业答案公布:

问题1:主键都有哪些方式?

自动增长式、

手动增长式 、

UniqueIdentifier、

联合式(复合式),就是组合主键、

时间序列+随机数式、

“COMB(Combine)”类型。

问题2:本次实战案例建立的主键采用哪种方式?

自动增长式

问题3:猜猜金蝶K3WISE建立的主键采用哪种方式?

手动增长式 ,金蝶是调用存储过程GetICMaxNum,实现ID增长

set @FNInterID=0

exec GetICMaxNum 'POOrder',@FNInterID
output,1,16394

问题4:谈谈手工主键增长设置具体实现思路?(选答)

手动增长型的字段,也就是说主键的值需要自己维护。

1:通常情况下需要建立一张单独的表存储当前主键键值。:

2:然后手工实现键值数据递增。在SQL Server中可以编写这样一个存储过程,让取键值的过程自动进行。

3:通过调用存储过程,我们可以获得最新键值,确保不会出现重复。

问题5:GUID主键是啥玩意?(选答)

guid主键,意思是建立一个字段,类型是UniqueIdentifier

然后把这个字段设为主键,就是guid主键。

因为这个类型的字段,经常看到字段名取名GUID,其实就是UniqueIdentifier主键。

二、Sql Server 基础培训《进度2-关于主键(知识点学习)》的更多相关文章

  1. 五、Sql Server 基础培训《进度5-数据类型(知识点+实际操作)》

    知识点: ================================================= ============================================= ...

  2. 三、Sql Server 基础培训《进度3-是否使用外键(知识点学习)》

    学习作业3: 问题1:你觉得外键有哪些适用情况?哪些不适用情况?   问题2:本次实战案例,由你来架构,你觉得有必要建立外键吗? 说明你的理由?     ======================= ...

  3. 四、Sql Server 基础培训《进度4-插入数据(实际操作)》

    知识点: 假设有订单表 CREATE TABLE Order ( ID int identity(1,1) not null primary key, --内码 BillNo varchar(100) ...

  4. 一、Sql Server 基础培训《进度1-建库建数据表(实际操作)》

    知识点: 1.建数据库示例参考 --创建一个数据库名为‘dbtest’ create database dbtest go --打开数据库 dbtest use dbtest go 2.建表示例参考 ...

  5. 八、Sql Server 基础培训《进度8-查询多种写法》(实际操作)

    知识点: 假设学生表.班级表.年级表 学生表(student) 内码 学生姓名 班级内码 001 张三 1002 002 李四 1002 003 王五 1003 004 钱六 1001 班级表(cla ...

  6. 九、Sql Server 基础培训《进度9-复杂查询练习》(实际操作)

    知识点: 复杂查询1:统计全校有多少个男生.有多少个女生? 写法1(分组): select sex as 性别,count(*) as 人数 from student group by sex 写法2 ...

  7. 七、Sql Server 基础培训《进度7-笛卡尔积(知识点+实际操作)》

    知识点: 1.笛卡尔介绍 笛卡尔,近代法国著名哲学家.物理学家.数学家.神学家. 主要成就概述 笛卡尔在科学上的贡献是多方面的.笛卡尔不仅在哲学领域里开辟了一条新的道路,同时笛卡尔又是一勇于探索的科学 ...

  8. 六、Sql Server 基础培训《进度6-更新删除(实际操作)》

    知识点: 假设,创建表test1,test2. drop table test1 create table test1 ( FID int identity(1,1), FBillNo varchar ...

  9. SQL Server数据库表重置自增主键号(通常是指ID)

    执行 DBCC CHECKIDENT ('table_name', NORESEED) 以确定列中的当前最大值 然后使用 DBCC CHECKIDENT ('table_name', RESEED,n ...

随机推荐

  1. python-循环小练习

    作业:登录程序,最多循环输入三次,账号密码校验输入为空的情况: 知识点总结 1.while和for循环的区别是,1个需要定义计数器,1个不需要定义计数器: 2.break正常循环结束后会用到,意思是不 ...

  2. webpack常用loader和plugin及打包速度优化

    优化 或 也可以用: 备用: 慎用的配置,用的不好会增加打包时间: 代码丑化插件:

  3. 动态规划-最长上升子序列(LIS)

    时间复杂度为〇(nlogn)的算法,下面就来看看. 我们再举一个例子:有以下序列A[]=3 1 2 6 4 5 10 7,求LIS长度. 我们定义一个B[i]来储存可能的排序序列,len为LIS长度. ...

  4. pygame-KidsCanCode系列jumpy-part16-enemy敌人

    接上回继续,这次我们要给游戏加点难度,增加几个随机出现的敌人,玩家碰到敌人后Game Over. 最终效果如下,头上顶个"电风扇"的家伙,就是敌人. 一.先定义敌人类 # 敌人类 ...

  5. ps保存时提示最大兼容

    在菜单:编辑-首选项-文件处理可以设置要不要询问

  6. VS2017环境下安装AO10.2的方法

    软件版本 Visual Studio的全称.简称及版本号对应关系为: Microsoft Visual Studio 2002 VS2002 VC7.0 Microsoft Visual Studio ...

  7. 自动化中app支持schema跳转

    android schema: String url = "adb -s " + udid + " shell am start -a 'android.intent.a ...

  8. Ant之build.xml配置详解【转】

    原文:https://blog.csdn.net/mevicky/article/details/72828554 前言国内关于build.xml的配置资料太零散了,实在是受不了,故而将自己的笔记整理 ...

  9. 正则双重过滤 /// splitKey1 第一个正则式匹配 /// splitKey2 匹配结果中再次匹配进行替

    /// <summary> /// 正则双重过滤 /// splitKey1 第一个正则式匹配 /// splitKey2 匹配结果中再次匹配进行替换 /// </summary&g ...

  10. [转]numpy 100道练习题

    100 numpy exercise 翻译:YingJoy 网址: https://www.yingjoy.cn/ 来源:https://github.com/rougier/numpy-100 Nu ...