数据库中主键和外键的设计原则

主键和外键是把多个表组织为一个有效的关系数据库的粘合剂。主键和外键的设计对物理数据库的性能和可用性都有着决定性的影响。 

    必须将数据库模式从理论上的逻辑设计转换为实际的物理设计。而主键和外键的结构是这个设计过程的症结所在。一旦将所设计的数据库用于了生产环境,就很难对这些键进行修改,所以在开发阶段就设计好主键和外键就是非常必要和值得的。 

首先来谈:主键。 

关系数据库依赖于主键 --- 它是数据库物理模式的基石。主键在物理层面上只有两个用途: 
1. 惟一地标识一行。 
2. 作为一个可以被外键有效引用的对象。 

基于以上这两个用途,下面给出了我在设计物理层面的主键时所遵循的一些原则: 

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

         2. 主键应该是单列的,以便提高连接和筛选操作的效率。 

        注:使用复合键的人通常有两个理由为自己开脱,而这两个理由都是错误的。其一是主键应当具有实际意义,然而,让主键具有意义只不过是给人为地破坏数据库提供了方便。其二是利用这种方法可以在描述多对多关系的连接表中使用两个外部键来作为主键,我也反对这种做法,理由是:复合主键常常导致不良的外键,即当连接表成为另一个从表的主表,而依据上面的第二种方法成为这个表主键的一部分,然,这个表又有可能再成为其它从表的主表,其主键又有可能成了其它从表主键的一部分,如此传递下去,越靠后的从表,其主键将会包含越多的列了。 

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

         注:这项原则对于那些经常需要在数据转换或多数据库合并时进行数据整理的数据并不适用。 

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

         5. 主键应当有计算机自动生成。如果由人来对主键的创建进行干预,就会使它带有除了惟一标识一行以外的意义。一旦越过这个界限,就可能产生认为修改主键的动机,这样,这种系统用来链接记录行、管理记录行的关键手段就会落入不了解数据库设计的人的手中。

时间: 2025-01-02 05:17:30

数据库中主键和外键的设计原则的相关文章

如何区分SQL数据库中的主键与外键_MsSql

一.什么是主键.外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如 : 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的,学号就是一个主键 用户表(用户名.密码.登录级别) 其中用户名是唯一的, 用户名就是一个主键 上机记录表(卡号,学号,姓名.序列号) 上机记录表中单一一个属性无法唯一标识一条记录,学号和姓名的组合才可以唯一标识一条记录,所以 学号和姓名的属性组是一个主键 上机记录表中的序列号不是成绩表的

如何区分SQL数据库中的主键与外键

一.什么是主键.外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如 : 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的,学号就是一个主键 用户表(用户名.密码.登录级别) 其中用户名是唯一的, 用户名就是一个主键 上机记录表(卡号,学号,姓名.序列号) 上机记录表中单一一个属性无法唯一标识一条记录,学号和姓名的组合才可以唯一标识一条记录,所以 学号和姓名的属性组是一个主键 上机记录表中的序列号不是成绩表的

快速理解MySQL中主键与外键的实例教程_Mysql

主键与外键的关系,通俗点儿讲,我现在有一个论坛,有两张表,一张是主贴 thread,一张是回帖 reply 先说说主键,主键是表里面唯一识别记录的字段,一般是帖子id,体现在访问的时候,例如是 thread.php?id=1   表示我要访问的是帖子id是1 的帖子- 再来说说外键,当我们删除某个帖子的时候,需要执行另一个操作,就是删除所有回帖,如果正常情况下,我们需要执行两次delete操作(thread和 reply),这时候如果存在外键,例如,在reply 表里面建立一个指向thread表

c#-数据库中主键信息存在,注册信息中主键信息重复问题

问题描述 数据库中主键信息存在,注册信息中主键信息重复问题 public partial class 挂号界面 : Form { OleDbConnection con = new OleDbConnection(); string str = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:hospitaldata.accdb"; public 挂号界面() { InitializeComponent(); con.Connecti

《SQL初学者指南(第2版)》——1.4 主键和外键

1.4 主键和外键 请留意每个表的第1列:即Customers表中的CustomerID和Orders表中的OrderID.这些列通常称为主键(primary key).主键之所以有用和有必要,有两个原因.首先,它们使你能够唯一地标识表中一个单独的行.例如,如果想要查找Bob Davis这一行,我们可以只使用CustomerID列来获取数据.主键还确保了唯一性.当指定CustomerID列作为主键时,就保证了表中的该列针对每一行都拥有一个唯一的值.即使在数据库中有两个不同的人都叫做Bob Dav

《SQL初学者指南》——1.6 主键和外键

1.6 主键和外键 SQL初学者指南请留意每个表的第一列:即Customers表中的CustomerID和Orders表中的OrderID.这些列通常称为主键(primary key).主键之所以有用和有必要,有两个原因.首先,它们使你能唯一地标识表中一个单独的行.例如,如果想要查找William Smith这一行,我们可以只使用CustomerID列来获取数据.主键还确保了唯一性.当指定CustomerID列作为主键时,就保证了表中的该列针对每一行都拥有一个唯一的值.即使在数据库中,有两个不同

数据-Mysql中设置表的外键的时候报错

问题描述 Mysql中设置表的外键的时候报错 这个是原句子: ALTER TABLE emp ADD CONSTRAINT id_fk FOREIGN KEY (deptno) REFERENCES Dept (deptno); 就是想把emp表的deptno设置为外键,该列的数据引用Dept表的主键列deptno的数据.然后,报错信息如下: Cannot add or update a child row: a foreign key constraint fails (emp.#sql-1a

hibernate两个表之间的关联关系,主键和外键的类型不同

问题描述 hibernate两个表之间的关联关系,主键和外键的类型不同 现在有两个表,表a和b两个表,a里面的主键为aid,b的主键为bid,b中有a的外键aid,现在aid的类型为int类型的,b表中的aid为string类型的,如何建立关联关系才能够解决当前报错的问题呢?报错信息如下:Wrong column type in b for column aid. Found: varchar expected: integer这个错误的意思是说,在b表中找到了varchar类型的aid,但是我

Mysql中增加与取消外键约束语句

语法 [CONSTRAINT [symbol]] FOREIGN KEY     [index_name] (index_col_name, ...)     REFERENCES tbl_name (index_col_name,...)     [ON DELETE reference_option]     [ON UPDATE reference_option] reference_option:     RESTRICT | CASCADE | SET NULL | NO ACTION