zoukankan      html  css  js  c++  java
  • 理解newid()和newsequentialid()

    原文地址:http://blog.csdn.net/xushichang/article/details/4390957 

    1.:newsequentialid 函数比起 newid 函数最大的好处是:如果你在一个 UNIQUEIDENTIFIER 字段上建立索引,使用 newid 产生的新的值是不固定的,所以新的值导致索引B+树的变化是随机的。而 newsequentialid 产生的新的值是有规律的,则索引B+树的变化是有规律的。有规律和无规律就会带来性能的改进。

    2:UNIQUEIDENTIFIER做主键(Primary Key)是一件很方便的事情,在数据合并等操作中有不可替代的优势
    但是由于普通的GUID的分散性使得如果主键加上聚集索引(Clustered Index)会导致在插入记录时效率大大降低

    SQL SERVER 2005中新增了一个NEWSEQUENTIALID的函数,MSDN的解释是:
    在指定计算机上创建大于先前通过该函数生成的任何 GUID 的 GUID。
    NEWSEQUENTIALID() 不能在查询中引用。
    注:即只能做为数据库列的DEFAULT VALUE,不能执行类似SELECT NEWSEQUENTIALID()的语句
    只有当计算机没有网卡时,NEWSEQUENTIALID() 生成的 GUID 才在该特定计算机中是唯一的。
    注:这句话是错误的,应该是只有只有当计算机有网卡时,生成的GUID才是全球唯一
    您可以使用 NEWSEQUENTIALID() 生成 GUID 以减少叶级别索引上的页争用。

    使用例子:

    create table #dd
    (
    fid uniqueidentifier NULL  DEFAULT (NEWSEQUENTIALID()),
     fname [nvarchar](20))

    insert into #dd(fname)values('dddff')

    select * from #dd where fid > 'D8407C7D-0E7C-DE11-94B0-001A4DDD5F17' and fid<'E2507993-0E7C-DE11-94B0-001A4DDD5F17'

    但是使用NEWSEQUENTIALID却不是那么一帆风顺
    1. 如何获得生成的GUID
    如果生成的GUID所在字段做为外键要被其他表使用,我们就需要得到这个生成的值
    通常,PK是一个IDENTITY字段,我们可以在INSERT之后执行 SELECT SCOPE_IDENTITY()来获得新生成的ID
    但是由于NEWSEQUENTIALID()不是一个INDETITY类型,这个办法是做不到了,而他本身又只能在默认值中使用,不可以事先SELECT好再插入,那么我们如何得到呢?有以下两种方法:

    --1. 定义临时表变量 
    DECLARE @outputTable TABLE(ID uniqueidentifier)
    INSERT INTO TABLE1(col1, col2)
    OUTPUT INSERTED.ID INTO @outputTable
    VALUES('value1', 'value2')
    SELECT ID FROM @outputTable

    --2. 标记ID字段为ROWGUID(一个表只能有一个ROWGUID)
    INSERT INTO TABLE1(col1, col2)
    VALUES('value1', 'value2')
    --在这里,ROWGUIDCOL其实相当于一个别名
    SELECT ROWGUIDCOL FROM TABLE1


    2. 如何设定DEFAULT VALUE为NEWSEQUENTIALID()
    通过UI的方式设定默认值时,由于SQL SERVER 2005的BUG(即使是SP2也没有解决),导致我们设置了默认值为NEWSEQUENTIALID()保存时会出现以下错误:
    Warning were encountered during the pre-save validation process, and might result in a failure during save. Do you want to continue attempting to save?
    'Table1' Table
    -Error validating the default for column 'Id'
    有两种方式可以解决:要么直接点Yes,要么通过CREATE TABLE语句来建表。

    通过客户端的方式,也可以通过调用windows api产生sequential的guid,虽说可以省去上面提到的两种麻烦,但是经过我测试,效果不是那么好。
    我建立了一个表有ID和TIMESTAMP两个字段,用NEWSEQUENTIALID()和客户端两种方法生成记录,并按ID和TIMESTAMP两种方式进行排序。
    NEWSEQUENTIALID()版本的结果永远一样。而客户端生成就有一些问题,如果连续运行程序,表现良好,如果间隔一段时间后继续运行,新生成的记录就不一定大于之前生成的记录,而每次间隔之间连续运行的部分,仍然表现良好。
    客户端生成sequential guid代码如下

     1    public static class SequentialGuid
     2    {
     3        [DllImport("rpcrt4.dll", SetLastError = true)]
     4        static extern int UuidCreateSequential(out Guid guid);
     5
     6        public static Guid NewGuid()
     7        {
     8            const int RPC_S_OK = 0;
     9
    10            Guid guid;
    11            int result = UuidCreateSequential(out guid);
    12            if (result != RPC_S_OK)
    13           {
    14                throw new ApplicationException("Create sequential guid failed: " + result);
    15            }
    16
    17            return guid;
    18        }
    19    }
  • 相关阅读:
    pytest学习(2)
    pytest学习(1)
    facets学习(1):什么是facets
    window10下部署flask系统(apache和wsgi)
    python tips:列表推导
    python的一致性(1)sorted和len
    THULAC:一个高效的中文词法分析工具包(z'z)
    EAScript 2016的新增语法(1)
    python的property的用法
    python算法:LinkedList(双向线性链表)的实现
  • 原文地址:https://www.cnblogs.com/niaowo/p/4820566.html
Copyright © 2011-2022 走看看