创建基本表结构

5.3.1 创建基本表结构(1)

如下是CREATE TABLE语句的基本语法:

 
  
  1. CREATE TABLE [<数据库>.][<模式>.]<表名>  
  2. (  
  3.        <指定列>   

如果你查看在线图书,你会发现还有一大堆额外的设置项,它们可以让你把表放到一个文件组中,将表分区到多个文件组中,控制将max或溢出的数据放置到何处,如此等等。在第9章讲表结构和索引时,会讨论针对不同的文件组,把你的数据放置到何处的问题。

CREATE子句很直接:

 
  
  1. CREATE TABLE [<数据库>.][<架构>.]<表名> 

我将展开讲尖括号(<和>)中的内容。任何在方括号([和])中的东西都是可选的。

<数据库>:在CREATE TABLE语句中很少需要指定数据库。如果不指定,默认的是当前正在执行该语句的数据库。如果指定了数据库,则意味着脚本只能在一个数据库中执行,一旦需要在同一台服务器上,用同一份未加变化的脚本创建备用的数据库,我们就没法满足要求。

<模式>:这是表所属的模式。

<表名>:这是表的名字。在5.2.1节中的"表命名"一节,我简单地讨论了如何给表命名。

提示 如果表名的首字母是一个单独的#号,则该表是一个临时表。如果表名开始的头两个字母是##,则该表是一个全局临时表。因为临时表只是个保持复杂类型中间结果的机制,在数据库设计中它并不占据重要的位置,所以不要在数据库设计中使用它们。

在数据库中,模式和表名的组合必须是唯一的。

注解 SQL Server 2005之前,名字的第二个部分是所有者,并且,几乎所有的最佳实践指南都建议,所有的表都由dbo(数据库用户)所拥有。

同时要注意的是,模式这个词有两种用法:一种指的是数据库中对象的容器,另一种指的仅仅是模式中的表。当我使用这个词时,我会尽量说清楚我用的是哪个意思。

1. 模式

本书第一个大节中,实现后数据库的每张表都被设置了模式。在SQL Server 2005中,将对象名中所有者部分变成了更合适的模式名。一个模式就是一个命名空间:一个在数据库内部包含了其他数据库对象的容器。模式有一点很棒,那就是它并没有和用户紧密捆绑到一起,你可以在不改变暴露出去的对象名的情况下删除某个用户。改变模式的所有者也就改变了表的所有者。(这是用ALTER AUTHORIZATION语句实现的。)

在SQL Server 2000及更早的版本中,表的所有者是用户;从SQL Server 2005开始,用户拥有的是模式,表包含在模式中。正如在2000中的情况一样,普通情况下推荐的最佳实践是:所有的表都由dbo用户所拥有。现在,最佳实践是让dbo拥有模式,但是,这并不意味着必须让每个模式都在命名中包含dbo字样。

不光表被绑定到特定的模式上,几乎任何对象都被绑定到了模式上。你可以用如下的命名方法来访问对象:

 
  
  1. [<数据库名>.][<模式名>.]对象名 

<数据库名>默认是当前数据库。<模式名>默认是用户的默认模式。一般说来,最好在所有SQL语句中都总是指明模式,因为这可以省得SQL去决定用哪个模式(当不指明模式时,该调用被认为是依赖于调用者的)。

为了方便使用,可以分割数据库中的对象,这时模式可以发挥很大的作用。如果你看看AdventureWorks数据库,就会发现所有的表并不是被dbo所"拥有",反之,它们现在是不同模式的成员。例如,使用新的sys.schemas系统视图,你可以列出数据库中的模式:

 
去掉所有的系统模式(自己运行这个查询看看),AdventureWorks数据库有如下模式:
创建基本表结构_第1张图片 
举个例子,现在让我们看看Purchasing模式所拥有的各个表:
 
参见下表:
创建基本表结构_第2张图片 

如果你使用单部分名字访问一个对象,在SQL Server 2005版之前的数据库中,所有者总是默认为dbo。在2005和之后的版本中,你可以指定一个不是dbo模式的默认模式(这模仿了以前版本的行为,使得向后兼容更容易些)。此时,当你执行"SELECT列名FROM表名"时,并不是按照默认的"dbo.表名"执行,而是使用了"默认模式名.表名"。

通过如下代码指定默认架构:

 
  
  1. CREATE USER <模式用户>   
  2.        FOR LOGIN <模式用户>  
  3.        WITH DEFAULT SCHEMA = 模式名

5.3.1 创建基本表结构(2)

也可以用一个ALTER USER命令来修改现有用户的默认模式(很不幸,只能对基本用户这样做,对基于Windows组的用户不能这样做)。之所以说模式如此之好,其原因在于你可以在模式的层次上处理权限,而不用在逐个对象的层次上干这件事。当你用列表查看对象时,比如,在管理Studio中查看时,模式也给了你一个逻辑分组。

我不打算在本书的这部分深入讨论运用模式处理安全的细节,我所要指出的是,这是个好想法。在整本书中,只要举例,我就会对表所处的模式命名。在本书所设计的任何系统中,模式都是其一部分,这是因为只要我们进一步深入讨论数据库,前面有关模式的做法就是不可或缺的最佳实践。现在,让我们短暂地跳回现实中,我预期在生产系统中开始使用模式会经历一个漫长的过程,因为在过去的岁月中,"使用模式"这种方法并不常见。第8章会更多地讨论将模式用于安全。

对MovieRental数据库中的所有表,我将创建如下3个模式。我将以创建数据库的用户身份登录进来,进行以下的乃至所有的操作:

 
请注意,CREATE SCHEMA必须是批处理中的第一条语句。我们还将创建另一个模式,展示其他一些概念,不属于影片出租"体验"一部分的表,都放到这个模式中。
 

2. 列和基础数据类型

有箭头的行是用来定义列的:

 
  
  1. CREATE TABLE [<数据库>.][<模式>.]<表名>  
  2. (  
  3.     <列名> <数据类型> [<指定NULL>]   
  4.                       [IDENTITY [(种子,递增值)]  
  5.     --或者  
  6.     <列名> AS <计算出的定义 >  

<列名>占位符是你指定列名字的地方。

有以下两类列。

实现的:这是种普通的列,要为其分配物理存储空间,它的值要存储数据。

计算的(或虚拟的):这些列由计算构成,这些计算基于表中任何其他的物理列。

任何数据库中,大多数列都是实现列,但是,计算列有一些很酷的用处,因此,不要仅仅因为没怎么提到,就认为它们是没用的东西。使用计算列可以避免很多由代码造成的非规范化问题。(我会在本章后面展示计算列。)

3. 为NULL性

在创建列这个阶段,可以简单地将物理模型中的变为NULL来允许NULL,或者,变为NOT NULL来禁止NULL:

 
  
  1. <列名> <数据类型> [<NULL指定>] 

例如:

 
这里没什么值得惊讶的。即使完全不管"NULL指定",SQL Server也会对其使用默认值。要确定一个数据库当前关于NULL的默认属性,执行如下语句:
 
结果如下:
 
要为数据库设置一个默认值,可以用ALTER DATABASE。改变设置的语法如下:
 

提示 我们建议总是将这个值设为OFF,如此一来,当你忘记显式地设置该值时,才不会被可以为NULL的列所困。这些列总是飞快地填满NULL数据,搞得你必须去清理。

要为一个会话设置默认值,使用如下命令:

 
或者,当你想要默认为NULL时,设为ON。是的,将选项设置为OFF很让人困惑。这里有个例子:
创建基本表结构_第3张图片 
该代码返回的结果如下:
 

注解 由于地方不够,这里去掉了sp_help输出中的很多内容。sp_help返回关于表、列和约束的信息。

让我们以模型中的Inventory.Movie表为例,展示一下相关语法(见图5-23)。使用如下DDL创建表:

创建基本表结构_第4张图片 

创建基本表结构_第5张图片 
图5-23 要创建的Inventory.Movie表
这可以创建出表,尽管做法并不是"足够好",因为没什么内容可以阻止用户创建出重复行。在"代理键"一节中,我们将实现代理键(在这里是MovieId),然后用键约束来防止重复行。

你可能感兴趣的:(sql,server,数据库)