添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

SQL Server数据类型详解

摘要:通过本文,你将简单了解 SQLServer 数据类型,包括数字、字符串、二进制字符串、日期和时间以及其他数据类型。

SQL Server数据类型预览

在SQL Server中,列、变量和参数跟高级语言的变量一样,都有自己的数据类型。数据类型是指定这些对象可以存储的数据类型的属性。数据类型可以是整数,字符串,货币,日期和时间等类型。

SQL Server提供了一个数据类型的列表,该列表定义了可以使用的所有类型数据,例如定义列或声明变量。

下图说明了SQL Server数据类型系统:

注意,SQLServer 将在其未来版本中删除 ntext、 text 和 image 数据类型。因此,应该避免使用这些数据类型,而是使用 nvarchar (max)、 varchar (max)和 varbinar (max)数据类型。

精确的数据类型

精确数据类型存储精确数字,例如整数、小数或货币金额。

  • bit类型存储0、1或者NULL。
  • int, bigint, smallint和tinyint存储整形数据。
  • decimal和numeric数据类型存储具有固定精度和比例的数字,值得注意的是decimal和numeric是同义词。
  • money和smallmoney数据类型存储货币值
  • 下表说明了精确数据类型的特点:

    注意:如果开发新的应用程序,则应使用 time、 date、 datetime2和 datetimeoffest 数据类型。因为这些类型符合 SQL 标准,并且更具可移植性。此外,time、 datetime2和 datetimeoffest 具有更高的秒精度,并且 datetimeoffest 支持时区。

    字符串数据类型

    字符串数据类型允许存储固定长度(char)或可变长度数据(varchar)。文本数据类型可以在服务器的代码页中存储非 Unicode 数据。

    使用能够可靠地包含所有可能值的最小整数数据类型是一个很好的实践。例如,要在一个家庭中存储孩子的数量,TINYINT 就足够了,因为现在没有人可以生育超过255个孩子。然而,TINYINT 不足以存储一座建筑的楼层,因为一座建筑可以有超过255层。

    下面的语句创建一个由四个整数列组成的新表:

    CREATE TABLE dbo.sql_server_integers (
    	bigint_col bigint,
    	int_col INT,
    	smallint_col SMALLINT,
    	tinyint_col tinyint
    
    INSERT INTO dbo.sql_server_integers (
    	bigint_col,
    	int_col,
    	smallint_col,
    	tinyint_col
    VALUES
        9223372036854775807,
        2147483647,
        32767,
    

    要显示 dbo.sql_server_Integrgers表中存储的值,可以使用以下SELECT语句:

    SELECT
    	bigint_col,
    	int_col,
    	smallint_col,
    	tinyint_col
    	dbo.sql_server_integers;
    

    转换整数数据

    SQLServer将大于2,147,483,647的整数常量转换为DECIMAL(十进制)数据类型,而不是下面示例中所示的BIGINT数据类型(如下图r2):

    SELECT 2147483647 / 3 AS r1, 
    	   2147483649 / 3 AS r2;
    

    Decimal

    SQLServer DECIMAL数据类型概述

    若要存储具有固定精度和比例的数字,请使用DECIMAL数据类型。
    下面显示了DECIMAL数据类型的语法:

    DECIMAL(p,s)
    

    在这个句法中:

  • p是精度,它是将存储在小数点的左侧和右侧的最大十进制数字总数。精度的范围从1到38。默认精度为38。
  • s是小数点右侧存储的小数位数。刻度的范围为0到p(精度)。只有指定了精度p,才能指定比例。默认情况下,s为零。
  • 比如1.0234,那么p就是5,s是4
  • 最大占用存储大小取决于下表所示的精度:

    存储大小(bytes)

    SQL Server DECIMAL例子

    首先,创建一个由两列组成的新表: 一个DECIMAL和一个NUMERIC:

    CREATE TABLE dbo.sql_server_decimal (
        dec_col DECIMAL (4, 2),
        num_col NUMERIC (4, 2)
    

    然后插入数据

    INSERT INTO dbo.sql_server_decimal (dec_col, num_col)
    VALUES
        (10.05, 20.05);
    
    SELECT
        dec_col,
        num_col
        dbo.sql_server_decimal;
    

    最后尝试向表中插入一个新行,其值超过列定义中指定的精度和小数位数:

    INSERT INTO dbo.sql_server_decimal (dec_col, num_col)
    VALUES
        (99.999, 12.345);
    

    SQLServer报如下错误并终止语句:

    Arithmetic overflow error converting numeric to data type numeric.
    The statement has been terminated
    

    BIT数据类型概述

    SQLServer BIT数据类型是一个整数数据类型,可以是0、1或NULL值。

    SQL Server优化了BIT列的存储。如果表具有8个或更少的BIT列,则SQL Server将它们存储为1个byte(8bit)。如果表具有9个到16个bit的列,则SQL Server将它们存储为2个byte,依此类推。

    SQL Server将字符串值TRUE转换为1,FALSE转换为0。它还将任何非零值转换为1。

    SQL Server BIT例子

    下面的语句创建一个包含一个 BIT 列的新表:

    CREATE TABLE dbo.sql_server_bit (
        bit_col BIT
    

    将bit值1插入bit列:

    INSERT INTO dbo.sql_server_bit (bit_col)
    OUTPUT inserted.bit_col
    VALUES(1);
    
    bit_col
    -------
    (1 row affected)
    

    插入值0:

    INSERT INTO dbo.sql_server_bit (bit_col)
    OUTPUT inserted.bit_col
    VALUES(0);
    
    bit_col
    -------
    (1 row affected)
    

    如果将字符串值True插入bit列,SQL server会将其转换为位1:

    INSERT INTO dbo.sql_server_bit (bit_col)
    OUTPUT inserted.bit_col
    VALUES('True');
    
    bit_col
    -------
    (1 row affected)
    

    同样,SQL Server将false的字符串值转换为位0:

    INSERT INTO dbo.sql_server_bit (bit_col)
    OUTPUT inserted.bit_col
    VALUES('False');
    
    bit_col
    -------
    (1 row affected)
    

    SQLServer 将任何非零值转换为位1。例如:

    INSERT INTO dbo.sql_server_bit (bit_col)
    OUTPUT inserted.bit_col
    VALUES(0.5);
    
    bit_col
    -------
    (1 row affected)
    

    SQL Server CHAR数据类型概述

    如果要存储固定的长度,非Unicode字符串数据,则使用SQL Server Char数据类型:

    CHAR(n)
    

    在此语中,n指定字符串长度从1到8,000。

    因为 n 是可选的,如果不在数据定义或变量声明语句中指定它,它的默认值是1。

    只有当列中的值的大小固定时,才应该使用 CHAR 数据类型。

    将字符串值插入CHAR列时。如果字符串值的长度小于列中指定的长度,则 SQLServer 将会在此字符串后面使用空格来补齐,但是,当SELECT此字符串值时,SQLServer 会在返回该字符串值之前删除尾随空格。

    另一方面,如果插入长度超过列长度的值,SQLServer 将会报错。

    ISO标准规定char和character是同义词,所以可以互换使用,如下等价:

    char(10)
    character(10)
    

    SQL Server Char数据类型示例

    下面的语句创建一个包含 CHAR 列的新表:

    CREATE TABLE dbo.sql_server_char (
        val CHAR(3)
    

    请注意,如果您在数据库中没有test架构,则可以在创建SQL_SERVER_CHAR表格之前使用以下语句来创建它:

    CREATE SCHEMA test; 
    

    将一个固定长度的字符串插入 CHAR 列:

    INSERT INTO dbo.sql_server_char (val)
    VALUES
        ('ABC');
    

    如果尝试插入一个长度超过CHAR列指定的长度3的话就会报错:

    INSERT INTO dbo.sql_server_char (val)
    VALUES
        ('XYZ1');
    

    SQL Server报如下错误:

    String or binary data would be truncated.--字符串被截断了
    The statement has been terminated.--语句被终止
    

    以下语句将单个字符插入 dbo.sql_server_char 表的 val 列:

    INSERT INTO dbo.sql_server_char (val)
    VALUES
        ('A');
    

    在 SQLServer 中,LEN 函数返回指定列中不包含尾随空格的字符数,而 DATALENGTH 函数返回字节数。

    请看如下语句:

    SELECT
        LEN(val) len,
        DATALENGTH(val) data_length
        sql_server_char;
    

    即使字符"A"只是一个字符,但列所占字节数为固定为三个字符。

    NCHAR

    SQL Server NCHAR数据类型概述

    要在数据库中存储固定长度的 Unicode字符字符串数据,可以使用 SQL Server NCHAR 数据类型:

    NCHAR(n)
    

    在此语法中,n指定字符串长度从1到4,000。NCHAR值的存储大小为两倍n字节。

    ISO(国际标准化组织)规定了NCHAR和NATIONAL CHAR是同义词,因此可以相互替换使用。如下等价:

    NCHAR(10)
    NATIONAL CHAR(10)
    

    与CHAR数据类型类似,NCHAR仅用于存储固定长度的字符串。如果数据值的长度是可变的,则应考虑使用VARCHAR或NVARCHAR数据类型。

    CHAR和NCHAR

    下面是 CHAR 和 NCHAR 数据类型之间的主要区别:

    NCHAR

    注意:Unicode字符串必须加上前缀N,如:N'你是个好人',否则SQL Server可能无法识别某些Unicode字符

    跟CHAR一样,如果插入的字符串的长度大于列定义中指定的长度,则 SQLServer 将会报错。
    比如,如下语句插入两个字符的到dbo.sql_server_nchar表的val列(NCHAR(1)):

    INSERT INTO dbo.sql_server_nchar (val)
    VALUES
        (N'你好'); 
    

    SQL Server报如下错误:

    String or binary data would be truncated.--字符串被截断了
    The statement has been terminated.--语句被终止
    

    要知道 val 列的字符数和字节数,可以使用 LENDATALENGTH 函数,如下所示:

    SELECT
        len(val) length,
        DATALENGTH(val) data_length
        dbo.sql_server_nchar;
    

    VARCHAR

    SQL Server VARCHAR数据类型概述

    SQL Server VARCHAR数据类型用于存储可变长度的非Unicode字符串数据。用法如下:

    VARCHAR(n)
    

    在此语法中,n是最大可以存储的非Unicode字符个数,n 定义范围为1到8,000的字符串长度。如果不指定 n,则其默认值为1。

    声明varchar列的另一种方法是使用以下语法:

    VARCHAR(max)
    

    在此语法中,Max定义最大存储大小为\(2^{31}\)-1字节(2 GB)。

    一般来说,VARCHAR 值的存储大小是所存储的数据的实际长度加上2个字节。

    ISO(国际标准化组织)规定了VARCHAR,CHARVARYINGCHARACTERVARYING是同义词,因此可以相互替换使用。如下等价:

    VARCHAR(10)
    CHARVARYING(10)
    CHARACTERVARYING(10)
    

    SQL Server VARCHAR例子

    下面的语句创建一个包含一个 VARCHAR 列的新表:

    CREATE TABLE dbo.sql_server_varchar (
        val VARCHAR NOT NULL
    

    因为没有指定 val列的字符串长度,所以它默认为1。
    若要更改 val 列的字符串长度,请使用 ALTER TABLE ALTER COLUMN 语句:

    ALTER TABLE dbo.sql_server_varchar 
    ALTER COLUMN val VARCHAR (10) NOT NULL;
    

    以下语句将一个新字符串插入 dbo.sql_server_varchar 表的 val 列:

    INSERT INTO dbo.sql_server_varchar (val)
    VALUES
        ('SQL Server');
    

    该语句正常执行,因为字符串值的长度等于列定义中定义的长度10。

    下面的语句尝试插入新的字符串数据,其长度大于列的字符串长度:

    INSERT INTO dbo.sql_server_varchar (val)
    VALUES
        ('SQL Server VARCHAR');
    

    SQLServer 报错并终止语句:

    String or binary data would be truncated.--字符串被截断了
    The statement has been terminated.--语句被终止
    

    要知道 VARCHAR 列中存储的字符数和字节数,可以使用 LENDATALENGTH 函数,如下面的查询所示:

    SELECT
        LEN(val) len,
        DATALENGTH(val) data_length
        dbo.sql_server_varchar;
    

    NVARCHAR

    SQL Server NVARCHAR数据类型概述

    SQLServerNVARCHAR 数据类型用于存储可变长度的 Unicode 字符串数据:

    NVARCHAR(n)
    

    在此语法中,n定义最大可以存储的字符个数,n 定义范围为1到4,000的字符串长度。如果不指定字符串长度,则其默认值为1。

    声明 NVARCHAR 列的另一种方法是使用以下语法:

    NVARCHAR(MAX)
    

    在此语法中,Max定义最大存储大小为\(2^{31}\)-1字节(2 GB)。

    一般来说,NVARCHAR 值的实际存储大小(以字节为单位)是输入字符数的两倍再加上2个字节。

    ISO标准中,NVARCHARNATIONAL CHAR VARYINGNATIONAL CHARACTER VARYING等价,可以互换使用:

    NVARCHAR(10)
    NATIONAL CHAR VARYING(10)
    NATIONAL CHARACTER VARYING(10)
    

    VARCHAR和NVARCHAR

    下表说明了 VARCHAR 和 NVARCHAR 数据类型之间的主要区别:

    在此示例中,NVARCHAR 列的字符串长度默认为1。
    若要更改 val 列的字符串长度,请使用 ALTER TABLE ALTER COLUMN 语句:

    ALTER TABLE dbo.sql_server_Nvarchar 
    ALTER COLUMN val NVARCHAR (10) NOT NULL;
    

    以下语句将一个新字符串插入 dbo.sql_server_nvarchar 表的 val 列:

    INSERT INTO dbo.sql_server_varchar (val)
    VALUES
        (N'你是个好人');
    

    语句正常执行,因为字符串值的长度(5)小于列定义中定义的字符串长度(10)。

    下面的语句尝试插入一个长度大于 val 列的字符串长度的新字符串数据:

    INSERT INTO dbo.sql_server_nvarchar (val)
    VALUES
        (N'你是个好人,你是个好人,你是个好人');
    

    SQLServer 报错并终止语句:

    String or binary data would be truncated.--字符串被截断了
    The statement has been terminated.--语句被终止
    

    想知道存储在NVARCHAR列中的值的字符数和以字节为单位的存储大小,可以使用 LENDATALENGTH 函数,如下所示:

    SELECT
        LEN(val) len,
        DATALENGTH(val) data_length
        dbo.sql_server_nvarchar;
    

    DATETIME2

    SQLServer DATETIME2简介

    DateTime2是从SQL2008开始支持一个新的日期数据类型。
    若要在数据库中同时存储日期和时间,请使用 SQLServer DATETIME2数据类型。

    语法如下:

    DATETIME2(n)
    

    这个n是秒精度,n的范围是0到7,DATETIME(n)格式是这样的yyyy-MM-dd HH:mm:ss.fffffff,这个n代表的就是f的个数,也就是秒的精度。

    下面的语句说明如何创建由 DATETIME2列组成的表:

    CREATE TABLE table_name (
        column_name DATETIME2(3),
    

    DATETIME2有两个组成部分: Date(日期)和Time(时间):

  • 日期的范围从0001年1月01日(0001-01-01)到9999年12月31日(9999-12-31)。
  • 时间的范围从00:00:00到23:59:59.9999999。
  • DATETIME2(n)值的存储大小取决于秒的精度n的大小,对于小于3的精度,它需要6个字节; 对于介于3和4之间的精度,它需要7个字节; 对于所有其他精度,它需要8个字节。

    DATETIME2的格式如下:

    YYYY-MM-DD hh:mm:ss[.fff...](f个数为n)
    

    在此格式中:

  • YYYY 是一个四位数字,代表一个年份,例如2018,它的范围从0001到9999。
  • MM 是一个两位数字,表示一年中的一个月,例如12。它的范围从01到12。
  • DD 是两位数字,代表指定月份的某一天,例如23。范围从01到31。
  • hh是代表小时的两位数数字。它的范围从00到23。
  • mm是代表分钟的两位数数字。它的范围从00到59。
  • ss是一个两位数,代表秒。范围从00到59。
  • fff...代表的是秒精度,为0到7位数,范围从0到9999999。具体位数取决于Datetime2(n)中的n
  • SQL Server DATETIME2示例

    以下语句创建了一个数据类型为DateTime2列的新表:

    CREATE TABLE dbo.product_colors (
        color_id INT PRIMARY KEY IDENTITY,
        color_name VARCHAR (50) NOT NULL,
        created_at DATETIME2
    

    要将当前日期和时间插入create_at 列,可以使用以下带 GETDATE()函数的 INSERT 语句:

    INSERT INTO dbo.product_colors (color_name, created_at)
    VALUES
        ('Red', GETDATE()); 
    

    GETDATE()函数跟其他数据库系统中的NOW()很想,比如MySQL。

    向DATETIME2列中插入字符串格式的日期,请使用以下语句:

    INSERT INTO dbo.product_colors (color_name, created_at)
    VALUES
        ('Green', '2018-06-23 07:30:20');
    

    如果要将create_at列的默认值设置为当前日期和时间,则使用以下ALTER TABLE语句:

    ALTER TABLE dbo.product_colors 
    ADD CONSTRAINT df_current_time 
    DEFAULT CURRENT_TIMESTAMP FOR created_at;
    

    在此语句中,我们使用 CURRENT_TIMESTAMP 作为 create_at 列的默认值。注意 CURRENT_TIMESTAMP 返回与 GETDATE()函数相同的值。
    现在,向表中插入新行而不指定created_at列的值时,SQL Server将使用该列的当前日期和时间值:

    INSERT INTO production.product_colors (color_name)
    VALUES
        ('Blue');
    

    SQL Server DATE简介

    要存储日期类型,使用DATE类型,语法如下

    不像DATETIME2类型,DATE数据类型只包含日期部分,范围是公元1年1月1日(0001-01-01)到公元9999年12月31日(9999-12-31)。
    DATE存储大小固定为3字节,它的格式如下:

    YYYY-MM-DD
    

    在此格式中:

  • YYYY 是一个四位数字,代表一个年份,例如2018,它的范围从0001到9999。
  • MM 是一个两位数字,表示一年中的一个月,例如12。它的范围从01到12。
  • DD 是两位数字,代表指定月份的某一天,例如23。范围从01到31,取决于月份。
  • SQL Server DATE示例

    创建如下包含DATE数据类型列order_date的订单表(Order):

    CREATE TABLE dbo.orders (
    	order_id INT IDENTITY (1, 1) PRIMARY KEY,
    	customer_id INT,
    	order_status tinyint NOT NULL,
    	order_date DATE NOT NULL,
    

    以下示例返回订购日期早于2016年1月5日的所有订单:

    SELECT    
    	order_id, 
    	customer_id, 
    	order_status, 
    	order_date
    	sales.orders
    WHERE order_date < '2016-01-05'
    ORDER BY 
    	order_date DESC;
    

    向表中插入数据:

    INSERT INTO dbo.orders (
    	customer_id, 
    	order_status, 
    	order_date
    VALUES
            '2019-12-31',
    

    SQL Server TIME数据类型简介

    SQL Server TIME数据类型基于24小时时钟定义一天的时间。时间数据类型的语法如下:

    TIME(p)--n是秒精度
    

    TIME(p)类型的格式是hh:mm:ss[.nnnnnnn],其中p代表的是n的个数,也就是秒的精度,p范围是0-7,如果没指定默认是7。

    下面的示例说明如何创建具有 TIME 列的表:

    CREATE TABLE table_name(
        start_at TIME(0),
    

    TIME 值的默认格式为:

    hh:mm:ss[.nnnnnnn]
    

    在这个格式中:

  • hh是代表小时的两位数数字。它的范围从00到23。
  • mm是代表分钟的两位数数字。它的范围从00到59。
  • ss是一个两位数,代表秒。范围从00到59。
  • nnnnnnn代表的是秒精度,为0到7位数,范围从0到9999999。具体位数取决于Date(p)中的p。
  • SQL Server TIME数据类型示例

    下面的语句创建了一个名为sales.visits的表,其中包含两个 TIME 列,用于记录客户访问特定商店的时间:

    CREATE TABLE sales.visits (
        visit_id INT PRIMARY KEY IDENTITY,
        customer_name VARCHAR (50) NOT NULL,
        phone VARCHAR (25),
        store_id INT NOT NULL,
        visit_on DATE NOT NULL,
        start_at TIME (0) NOT NULL,
        end_at TIME (0) NOT NULL,
        FOREIGN KEY (store_id) REFERENCES sales.stores (store_id)
    

    sales.visits表插入一行数据:

    INSERT INTO sales.visits (
        customer_name,
        phone,
        store_id,
        visit_on,
        start_at,
        end_at
    VALUES
            'John Doe',
            '(408)-993-3853',
            '2018-06-23',
            '09:10:00',
            '09:30:00'
    

    DATETIMEOFFSET

    DATETIMEOFFSET数据类型简介

    DATETIMEoffSET允许您操作任何单个时间点,这是一个日期时间值,以及一个偏移量,该偏移量指定该日期时间与UTC(世界协调时间)的差异。

    DATETIMEOFFSET语法如下:

    DATETIMEOFFSET(p)
    

    p代表秒精度(即秒小数点位数),范围时0-7,
    若要声明 DATETIMEOffSET 变量,请使用以下语法:

    DECLARE @dt DATETIMEOFFSET(7)
    

    若要创建数据类型为 DATETIMEOffSET 的表列:

    CREATE TABLE table_name (
        column_name DATETIMEOFFSET(7)
    

    DATETIMEOffSET 的范围从公元1年1月1日(0001-01-01)到公元9999年12月31(9999-12-31)日。时间范围从00:00:00到23:59:59.9999999。

    DATETIMEOffSET值的格式如下:

    YYYY-MM-DDThh:mm:ss[.nnnnnnn][{+|-}hh:mm]
    
    2020-12-12 11:30:30.12345 
    

    或国际标准化组织格式:

    YYYY-MM-DDThh:mm:ss[.nnnnnnn]Z
    
    2020-12-12 19:30:30.12345Z.
    

    对于日期时间或时间值,时区偏移量指定相对于 UTC 的区偏移量。时区偏移量表示为[+|-] hh:mm.
    比如中国本地时(中国标准时间-CST)相对于UTC偏移量就是+8:00,所以中国本地使用的时间就是UTC +8:00时间。

    对于语法中的的[+|-] hh:mm:

  • hh是两位数字,范围从00到14,表示时区偏移中的小时数。
  • mm是两个数字,范围从00到59,表示时区偏移中额外的分钟数。
  • +(加)或-(减)指定时区偏移量是从 UTC 时间中加入还是减去,以返回本地时间。
  • 时区偏移量的有效范围为 -14:00至 + 14:00

    DATETIMEOFFSET示例

    首先,创建一个名为messages的表,该表有一个DATETIMEOFFSET列:

    CREATE TABLE messages(
        id         INT PRIMARY KEY IDENTITY, 
        message    VARCHAR(255) NOT NULL, 
        created_at DATETIMEOFFSET NOT NULL
    

    然后,在message表中插入一个具有 DATETIMEOffSET 值的当前UTC时间:

    INSERT INTO messages(message,created_at)
    VALUES('DATETIMEOFFSET demo',
            CAST(getutcdate() AS DATETIMEOFFSET));
    

    最后,从messages表中查询数据,并使用中国标准时间时区(CST)将存储的DATETIMEOFFSET值(UTC)转换为“中国标准时间”时区。

    SELECT 
        message, 
    	created_at 
            AS '世界协调时间'
        created_at AT TIME ZONE 'China Standard Time' 
            AS '中国标准时间',
        messages;
    

    通过SQL Server内置的视图sys.time_zone_info,可以查看目标时区的名称:

    select * from sys.time_zone_info
    

    详情参考官网

    SQL Server GUID简介

    我们世界上所有的东西都有编号,例如,书有ISBN,汽车有VIN,人有身份证号码。

    数字或标识符帮助我们明确地引用事物。例如,我们可以用身份证号511023198423854213来识别他。

    全局唯一标识符或 GUID 是这类 ID 号码的一个更广泛的版本。

    GUID保证在表、数据库甚至服务器之间是唯一的。

    在SQL Server中,GUID是16字节二进制数据类型,使用NEWID()函数生成:

    SELECT 
        NEWID() AS GUID;
    

    如果多次执行上述语句,每次都会看到不同的值。以下是其中之一:

    ------------------------------------ 3297F0F2-35D3-4231-919D-1CFCF4035975 (1 row affected)

    在 SQLServer 中,UNIQUEIDENTIFIER 数据类型保存GUID值。
    以下语句声明了类型为UNIQUEIDENTIFIER的变量,并为其分配了NEWID()函数生成的GUID值。

    DECLARE 
        @id UNIQUEIDENTIFIER;
    SET @id = NEWID();
    SELECT 
        @id AS GUID;
    ------------------------------------
    69AA3BA5-D51E-465E-8447-ECAA1939739A
    (1 row affected)
    

    使用SQL Server GUID值作为主键

    有时,我更喜欢为表的主键列使用GUID值,而不是使用整数。
    使用GUID作为表的主键具有以下优点:

  • GUID值在表,数据库甚至服务器之间是全球唯一的。因此,它允许您轻松合并来自不同服务器的数据。
  • GUID值不暴露信息,因此在URL等公共界面中使用更安全。例如,如果您有URLhttps://www.example.com/customer/100/URL,不难发现将有id为101、102等的客户。但是,使用GUID,这是不可能的:https://www.example.com/customer/F4AB02B7-9D55-483D-9081-CC4E3851E851/
  • 除了这些优点外,将GUID存储在表的主键列中还有以下缺点:

  • GUID值(16字节)比INT(4字节)甚至BIGINT(8字节)占用更多的存储空间。
  • GUID值使调试bug变得复杂,比如id=100与id=F4AB02B7-9D55-483D-9081-CC4E3851E851。
  • SQL Server GUID示例

    创建一个名为customers的新表:

    CREATE TABLE dbo.customers(
        customer_id UNIQUEIDENTIFIER DEFAULT NEWID(),
        first_name NVARCHAR(100) NOT NULL,
        last_name NVARCHAR(100) NOT NULL,
        email VARCHAR(200) NOT NULL
    

    插入两行数据:

    INSERT INTO 
        dbo.customers(first_name, last_name, email)
    VALUES
        ('John','Doe','john.doe@example.com'),
        ('Jane','Doe','jane.doe@example.com');
    

    查询数据:

    SELECT 
        customer_id, 
        first_name, 
        last_name, 
        email
        dbo.customers;
    

    本文详解了几乎所有的SQL Server数据类型,如果还有问题,欢迎加QQ(2439739932)与我交流.