sql数据库创建表与数据类型
1、创建表
本质上来说,sql语句就是源代码,所以应该用源代码工具来对其进行版本控制,比如SVN。
对于SQL SEVER而言,制表符、回车、空格所产生的效果是相同的,比如下面两条语句对于SQL SERVER来说效果时相同的。
2、命名表和列
表总是被创建在某个数据库的某个架构之下的。一个数据库可以包含多个有用相同名称的表,只要他们位于不同的架构之下。
一个表的完整名称包含一下三个部分:database.schema.tablename;
如果在引用一张表的时候没有指定架构名,则查找的顺序为:当前用户的默认架构;如果没有,则查找dbo架构;如果还没有,则查找失败。
你应该养成在sql server2005中总是指定架构名的习惯,这样不但能够消除歧义,而且还能带来一些性能上的提升。
在某些情况下,我们可以采用四段式的名字,第一段就是数据库的实例名。
3、保留关键字
这里要注意的是,有些SQL-92中的保留关键字,目前在SQL SERVER中还不是关键字,但是不排除以后他将会被作为关键字加入,所以为了防止以后的冲突,应该避免使用SQL-92中的所有关键字。
4、分隔标识符
如果我们使用了分隔标识符,我们不仅可以使用保留关键字作为标识符,还可以使用任何其他的符号作为对象名——不论他们是否符合标识符规则。有以下两种分隔标识符:
1)、方括号分隔;
2)、双引号分隔;必须用 SET QUOTED_IDENTIFIER ON 打开特定的选项后才可以使用。
ODBC和OLE DB的驱动程序在建立连接时,默认都会自动打开这个开关。我们可以通过如下的语句来判断当前的连接是否开启了该选项:
SELECT QUOTED_IDENTIFIER FROM sys.dm_exec_sessions WHERE session_id = @@spid
作者不推荐使用保留关键子,因为许多SQL SERVER的第三方工具对引用标识符处理的不是很好。
我们应该简单地制定一些命名惯例,而不是使用分隔标识符,这样我们就可以保护保留关键字,比如可以用表名的某些字母加上下划线来作为列名的前缀。
5、命名惯例
不建议使用匈牙利命名管理来作为SQL SERVER中的表的命名惯例;
6、数据类型
在选择数据类型时,应该避免浪费空间,同时应该注意为可能插入的数据留下足够的空间。
1)、选择数据类型
每个列要使用哪个数据类型主要取决于该列要存储的数据的本质,以及可能会对列数据进行的操作。
SQL SERVER2005有5中基本的数据类型:数字(numeric)、字符(charactar)、日期和时间(date and time)、大对象(large object, LOB)及其他。SQL SERVER 2005还支持一种名为sql_variant的可变数据类型,存储在sql_variant列中的数据可以是任何数据类型。
2)、Numeric数据类型
要关注的主要是要存储的数据的范围和精度要求。
Numeric可以分为精确和近似两类。精确数字值可以确保精确地存储数字,近似数字值可以表示的范围更大,但是不保证数字存储的精确性。
对于money和smallmoney,右边的四位是小数点后面的,而对于整数,小数点后面没有未。
Decimal和numeric数据类型对精度和数据范围都有很高的要求。下面这个语句就申明了一个decimal类型的变量,aNum decimal(8,4);
日期和时间数据类型
有两种,他们的默认日期都是1900年1月1号,00:00:00
Datetime,前面4个字节表示日期,后面4个字节表示时间。
smalldatetime;
该类型的内部存储区域被分为时间和日期两个部分,日期部分以1900年1月1号为准,算出来的是在此日期之前或者之后的天数。
对于datetime类型,时间部分存储的是午夜0点之后的时钟周期数,每个时钟周期是1/300秒,为3.33毫秒。
对于smalldatetime而言,时间部分存储的是午夜之后的分钟数。
字符数据类型
有4种
单字节:变长和固定长, varchar, char;最大长度为8000
Unicode:变长和固定长 nvarchar, nchar;最大长度为4000
另外,还可以定义MAX长度的字符串,被定义为 varchar(MAX) 长度的字符串在长度小于等于8000时,将作为普通的变长列处理,当实际长度超过8000时将被视作large object值。
要决定是用变长还是定长的数据类型时一个很困难的问题,他的答案并不直观和明显,一个普遍的规则是:变长的数据类型适合数据长度差异明显、并且数据变动不频繁的列。
使用变长数据类型可以节省巨大的存储开销,有时会带来一些微小的性能损失,其他时候能够提高性能。
与变长列有关的一个潜在的性能问题就是在一个几乎满地页面上增加某一行的大小时,特别是当这个表上刚好又有聚焦索引的时候。这时会导致非常大的开销,为什么很大,我还不是很清楚。
变长列导致每一行的长度大大减小,这种减小一方面带来了空间上的节约,更重要的是,它使得一个页面上能够存放的行数更多,我们能在一个页面上放的行数越多,I/O及其缓存命中的效率就越高。
在一个页面上存放的记录行数的计算规则是:页面大小/行的大小,余数要舍弃。
其他数据类型
Binary, varbinary,这些数值通过十六进制表现形式(0x作为前缀)来进行输入和显示;最大长度是8000;
Bit,可以存储0或1,并且只消耗单个位的存储空间,尽管如此,如果在一张表上只有单个比特列,这个列也将占用一整个字节。
Large object,包括text,ntext,image,最多可以存储2^31-1个字节。
Cursor
Rowversion,这是其正式名称timestamp的同义词。任何rowversion列的值在整个数据库中都是唯一的,并且每张表只能有一个rowversion类型的列。
Sql_variant,可以用于存储除了下面集中类型之外的所有数据类型,text, ntext, image, xml。
Table,可以用于存储某个函数返回的结果,还可以用来本地变量的数据类型;
Xml,xml有其自身的方法来获取和操作。
Uniqueidentifier,又被叫做GUID或UUID,可以使用NEWID或NEWSEQUENTIALID这两个系统函数来生成UUID的值。对该类型的值的操作只能是比较=, <, >, <=, >=, 还可以检验NULL值。
Sqlserver使用GUID的原因是为了在合并复制中使用。不是很明白。
NEWSEQUENTIALID和NEWID的主要区别在于NEWSEQUENTIALID是创建一个比以前在这台及其上用此函数创建的GUID要大的GUID,并且可以为我们的GUID值引入一个序列。
Uniqueidentifier的值不可能被穷举。
Uniqueidentifier列可以有一个叫做ROWGUIDCOL的特殊属性,一张表只能有一个uniqueidentifier列可以有该属性。
一张表可以有多个uniqueidentifier列。
在查询中可以使用ROWGUIDCOL关键字来应用ROWGUIDCOL属性的uniqueidentifier,这与IDENTITYCOL关键字来引用表示列类似。
如果要自动生成uniqueidentifier,则要把NEWID作为该列的默认值。