可以用如下方法进行设置:
第一,如果是用SQL语句建表,如下:(假设要让a和c组合作为主码)
create
table
t1(
a
int,
b
varchar(20),
c
int,
primary
key(a,c)
)
第二,如果用图形化界面做,按住ctrl键,然后选择a和c两个列,接着右键菜单选择“设置为主键”即可。
一个表中最多只能有一个主键,也可以没有。一个主键既可以是单一的字段构成,也可以是多个字段联合构成,如果是单一字段,只需在该字段后面标记primary
key即可,如果是多个字段联合构成,则需要采用最开始介绍的那种方式设置。
可用alter
table来定义主键。
步骤:
1、创建测试表:
create table test
(id int,
name varchar(10))2、如要以id为主键,可用如下语句:
如原来id允许为空,则多加一步,设置主键列不为空。
alter table test alter column id int not null如原来id不允许为空则跳过上一步,直接执行:
alter table test add primary key(id)3、再查此表,主键已创建:
关于数据库的逻辑设计 是一个很广泛的问题 本文主要针对开发应用中遇到在MS SQL Server上进行表设计时 对表的主键设计应注意的问题以及相应的解决办法
主键设计现状和问题
关于数据库表的主键设计 一般而言 是根据业务需求情况 以业务逻辑为基础 形成主键
比如 销售时要记录销售情况 一般需要两个表 一个是销售单的概要描述 记录诸如销售单号 总金额一类的情况 另外一个表记录每种商品的数量和金额 对于第一个表(主表) 通常我们以单据号为主键;对于商品销售的明细表(从表) 我们就需要将主表的单据号也放入到商品的明细表中 使其关联起来形成主从关系 同时该单据号与商品的编码一起 形成明细表的联合主键 这只是一般情况 我们稍微将这个问题延伸一下 假如在明细中 我们每种商品又可能以不同的价格方式销售 有部分按折扣价格销售 有部分按正常价格销售 要记录这些情况 那么我们就需要第三个表 而这第三个表的主键就需要第一个表的单据号以及第二个表的商品号再加上自身需要的信息一起构成联合主键;又或者其他情况 在第一个主表中 本身就是以联合方式构成联合主键 那么也需要在从表中将主表的多个字段添加进来联合在一起形成自己的主键
数据冗余存储 随着这种主从关系的延伸 数据库中需要重复存储的数据将变得越来越庞大 或者当主表本身就是联合主键时 就必须在从表中将所有的字段重新存储一次
SQL复杂度增加 当存在多个字段的联合主键时 我们需要将主表的多个字段与子表的多个字段关联以获取满足某些条件的所有详细情况记录
程序复杂度增加 可能需要传递多个参数
效率降低 数据库系统需要判断更多的条件 SQL语句长度增加 同时 联合主键自动生成联合索引
WEB分页困难 由于是联合主键方式(对于多数的子表) 那么在WEB页面上要进行分页处理时 在自关联时 难于处理
解决方案
从上面 我们已经看到现有结构存在着相当多的弊端 主要是导致程序复杂 效率降低并且不利于分页
为解决上述问题 本文提出 当应用系统后台数据库表间存在主从关系时 数据库表额外增加一非业务字段作为主键 该字段为数值型;或者当该表需要在应用中进行分页查询时 也应考虑如此设计 一般地 我们也可以几乎为任何表增加一个与业务逻辑无关的字段作为该表的主键字段
由于该字段要作为表的主键 那么其首要条件是要保证在该表中要具有唯一性 同时 结合SQL Server数据库自身的特性 可以为其建立一个自增列
create TABLE T_PK_DEMO ( U_ID BIGINT NOT NULL IDENTITY( ) –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL –其他列 CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 )
但是 SQL Server中的自增列却存在一个比较尴尬的事实 那就是该字段一旦定义和使用 用户无法直接干预该字段的值 完全由数据库系统自身控制
完全数据库系统控制 用户无法修改值
在数据库的发布和订阅时 使用自增列会比较麻烦
恢复部分数据时 使用自增列会比较麻烦
该列的值必须在插入数据后才能获取
鉴于此 建议不以自增列的方式来定义 而是参考Oracle数据库系统中序列 在SQL Server系统中实现类似Oracle数据库系统序列功能 这个具体在下面的小节中介绍 我们只需要按照普通字段的定义方式修改表定义为
create TABLE T_PK_DEMO ( U_ID BIGINT NOT NULL –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL –其他列 CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 )参照Oracle序列的功能 我们需要在SQL Server数据库中创建一个新表 以管理序列值
create TABLE T_DB_SEQ ( SEQ_NAMEVARchar( ) NOT NULL –序列名称 SEQ_OWNER VARchar( ) NOT NULL DEFAULT ’DBO’ –序列所有者(SYSTEM_USER) SEQ_CURRENT BIGINT NOT NULL DEFAULT –序列当前值 SEQ_MIN BIGINT NOT NULL DEFAULT –序列最小值 SEQ_MAX BIGINT NOT NULL DEFAULT –序列最小值 SEQ_MAX BIGINT NOT NULL DEFAULT –序列最大值 SEQ_STEPINT NOT NULL DEFAULT –序列增长步长 IF_CYCLEINT NOT NULL DEFAULT –是否循环( 不循环; 循环) CONSTRAINT T_DB_SEQ PRIMARY KEY CLUSTERED (SEQ_NAME SEQ_OWNER)–主键 )应用系统为需要创建自增列的表创建一个序列名称 在表“T_DB_SEQ”中反映为数据库中的一行
第一 需要为需要建立序列的表创建一个序列 采用方法 F_create_SEQ(序列名) 该函数传入序列的名称 在表“T_DB_SEQ”插入一行 序列的所有者 采用系统变量SYSTEM_USER
第二 获取下一个值 采用方法 F_GET_NEXT_SEQ_VAL(序列名) 该函数根据序列名获取该序列的下一个值 根据当前值与增长步长得到 同时 该函数保证在同时获取同一个序列时 应保证并发一致性
第三 将返回值返回到应用使用
此外 为保证应用的完整性 可能还需要提供一些方法的重载方法 同时提供一些其他方法
获取序列当前值 F_GET_SEQ_CUR_VAL(序列名)
设置序列值 F_SET_SEQ_VAL(序列名)
删除序列 F_DEL_SEQ(序列名)
判断序列是否存在 F_SEQ_exists(序列名)
在主从关系的表设计中 子表也使用序列字段作为唯一主键 将父表的序列字段作为外键关联
create TABLE T_PK_DEMO_C ( U_ID BIGINT NOT NULL –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL –其他列 P_ID INT NOT NULL –父表ID CONSTRAINT PK_T_PK_DEMO_C PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 CONSTRAINT FK_T_PK_DEMO_C FOREIGN KEY (P_ID) REFERENCES T_PK_DEMO(U_ID) ON delete CASCADE )使用序列的问题及解决办法
由于系统使用一个额外增加一个字段作为主键 因此没有为业务逻辑建立主键约束 比如在企业用户信息表中 要求企业中用户登录名必须唯一 一般在创建表时 以登录名作为主键 这个时候在数据库层自然的创建另一个主键唯一性约束 而现在没有使用登录名作为主键 那么就没有这个约束 解决办法
一是在数据库层解决 可以为该表创建一个唯一(UNIQUE)约束或者唯一索引 如
alter TABLE T_PK_DEMO ADD CONSTRAINT C_T_PK_DEMO UNIQUE NONCLUSTERED(COL_OTHER) 唯一约束
create UNIQUE INDEX IX_T_PK_DEMO ON T_PK_DEMO(COL_OTHER) – 唯一索引
二是在应用端解决 也就是在应用中判断该列是否有重复值 然后根据判断结果来保证唯一性
我们注意到 在之前的例子中 主键采用了NONCLUSTERED(非聚蔟)的索引方式 关于如何设计索引 不是本文的重点 在这里仅提供一个建立索引时采用聚蔟方式还是非聚蔟方式的一个一般原则
作为非业务字段的主键列 是一个没有重复值的 基本不进行更新 *** 作的列 并且 在SQL Server数据库中 聚蔟索引在一个表中只能有一个 因此 聚蔟索引非常重要 需要留给更重要的字段来使用 因此 对照上表和根据聚蔟索引的重要程度 在此处采用非聚蔟方式创建其索引
具体应用
采用这种主键设计方式 有诸多好处 这已经在前文说明 现在就以一个具体的应用来说明如何使用这个主键
lishixinzhi/Article/program/SQLServer/201311/22342
以上就是关于sql数据库中怎么设置多个列同时作为表的主键全部的内容,包括:sql数据库中怎么设置多个列同时作为表的主键、t sql 建好表后如何定义主键、SQL Server上进行表设计时表的主键设计问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)