SQL Server上进行表设计时表的主键设计问题

SQL Server上进行表设计时表的主键设计问题,第1张

关于数据库的逻辑设计 是一个很广泛的问题 本文主要针对开发应用中遇到在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

主键只有一个,但是可以设置为多个字段为主键,也即联合主键。外键就是自己设置了也即可以有多个,可以设置除主键以外的其他字段全部是外键的。

数据库的每张表只能有一个主键,不可能有多个主键。所谓的一张表多个主键,我们称之为联合主键。联合主键就是用多个字段一起作为一张表的主键。主键的主键的作用是保证数据的唯一性和完整性,同时通过主键检索表能够增加检索速度。

扩展资料:

一、数据库模型:

1、对象模型

2、层次模型(轻量级数据访问协议)

3、网状模型(大型数据储存)

4、关系模型

5、面向对象模型

6、半结构化模型

7、平面模型(表格模型,一般在形式上是一个二维数组。如表格模型数据Excel)

二、数据库的架构:

数据库的架构可以大致区分为三个概括层次:内层、概念层和外层。

1、内层:最接近实际存储体,亦即有关数据的实际存储方式。

2、外层:最接近用户,即有关个别用户观看数据的方式。

3、概念层:介于两者之间的间接层。

三、数据库索引:

索引跟字段有着相应的关系,索引即是由字段而来,其中字段有所谓的关键字段(Key Field),该字段具有唯一性,即其值不可重复,且不可为“空值(null)"。例如:在合并数据时,索引便是扮演欲附加字段数据之指向性用途的角色。故此索引为不可重复性且不可为空。

参考资料:

百度百科-数据库

CREATE TABLE `products_description` (

 `products_id` int(11) NOT NULL,

 `language_id` int(11) NOT NULL default

'1',

 `products_name` varchar(64) NOT NULL default

'',

 `products_description` text,

 `products_short_description` text,

 `products_url` varchar(255) default NULL,

 `products_viewed` int(5) default '0',

 PRIMARY KEY (`products_id`,`language_id`),

 KEY `products_name` (`products_name`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

指定primary key 时用 PRIMARY KEY (`products_id`,`language_id`),这样就能指定联合主键了

数据库中,关系模型中的主键是对每条数据记录的唯一标识,不可重复。主键可以是属性集,比如一张表R(A,B,C,D),主键为A+B是可以的。

主键,即主关键字(primary key)是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录。在两个表的关系中,主关键字用来在一个表中引用来自于另一个表中的特定记录。主关键字是一种唯一关键字,表定义的一部分。

一个表的主键可以由多个关键字共同组成,并且主关键字的列不能包含空值。主关键字是可选的,并且可在 CREATE TABLE 或 ALTER TABLE 语句中定义。

扩展资料:

建立主键应该遵循的原则:

1、主键应当是对用户没有意义的。如果用户看到了一个表示多对多关系的连接表中的数据,并抱怨它没有什么用处,那就证明它的主键设计地很好。

2、 永远也不要更新主键。因为主键除了唯一地标识一行之外,再没有其他的用途了,所以也就没有理由去对它更新。如果主键需要更新,则说明主键应对用户无意义的原则被违反了。

3、主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

4、主键应当由计算机自动生成。如果由人来对主键的创建进行干预,就会使它带有除了唯一标识一行以外的意义。一旦越过这个界限,就可能产生人为修改主键的动机。

参考资料来源:百度百科-主关键字

在JAVA开发中数据库的学习也是我们需要了解的,截下来几篇文章都是关于数据库的设计和应用,那么java课程培训机构废话不多说开始学习吧!

数据库的设计

数据库设计是基础,数据库优化是建立在设计基础之上的。好的数据库一定拥有好的设计。

数据库设计的目标是为用户和各种应用系统提供一个信息基础设施和高效的运行环境。

数据库的三大范式

第一范式1NF:所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。

第二范式2Nf:第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

第三范式3Nf:所有字段必须与主键直接相关,而不是间接相关。也可以理解为字段不要和其他非主键字段相关

注意:这三个范式尽可能去遵守,不是一定要墨守成规这只是让我们设计的表的时候,越靠近这些范式,可以使字段尽量的减小冗余但是有时候也可以根据实际需要小小的违背一下但是第三范式违反一下还可以接受,但是第一范式别违反

数据库设计的步骤

需求分析阶段

准确了解与分析用户需求(包括数据与处理)。是整个设计过程的基础,是最困难、最耗费时间的一步。

概念结构设计阶段

是整个数据库设计的关键--设计数据库的E-R模型图,确认需求信息的正确和完整

Entity_Relationship---实体之间的关系

一对一

一对多

多对一

参照那部分应该是引用前两个表的主键作为外键

同时,你这个题出的有问题,不应该各自设置主码,而是应该设置联合主键

所以,你这个表要这样建立

create table sc

(sno char(12) not null References sutdent_Info(sno),--References后边这些就是引用某表的某字段作为外键,下同

cno char(10) not null References course_Info(cno),

grade int,

Primary Key (sno, cno))--这句是设置联合主键

联合主键的意思就是指用2个或者是2个以上的字段组成的主键,用这个主键包含的字段作为主键,这个组合在数据表中是唯一,且附加上了主键索引。而数据库主键,指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。

扩展资料:

联合主键的作用如下:

1、保证实体的完整性。

2、加快数据库的 *** 作速度。

3、在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。

4、DBMS自动按主键值的顺序显示表中的记录。

参考资料:

百度百科-数据库主键

以上就是关于SQL Server上进行表设计时表的主键设计问题全部的内容,包括:SQL Server上进行表设计时表的主键设计问题、数据库建表时一个表最多可以有几个主键,几个外键、XAMPP中的mysql数据库中如何设置联合主键等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9647640.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存