主键和外键的作用

标签: 主键 外键 | 发表时间:2013-12-23 02:34 | 作者:amzkqi
出处:http://blog.csdn.net

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

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

主键:

关系数据库依赖于主键---它是数据库物理模式的基石。主键在物理层面上只有两个用途:

        1. 惟一地标识一行。

        2. 作为一个可以被外键有效引用的对象。

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

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

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

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

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

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

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

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

转载: http://www.cnblogs.com/tianyamoon/archive/2008/04/02/1134394.html

数据库外键的使用

外键的作用我认为主要有两个:一个是让数据库自己通过外键来保证数据的完整性和一致性,一个就是能够增加ER图的可读性。我觉得第二点的重要性甚至比第一点还高。

有些人认为外键的建立会给开发时操作数据库带来很大的麻烦,因为数据库有时候会由于没有通过外键的检测而使得开发人员删除,插入操作失败,他们觉得这样很麻烦,其实这正式外键在强制你保证数据的完整性和一致性,这是好事儿。

应该说如果系统比较小,外键的作用可能不会很明显,如果你的系统后台有几百个表的话,没有外键的数据库设计是我无法想象的,有一个基础数据的表:商品,其他表都保存商品ID ,查询时需要连表来查询商品的名称,单据1的商品表中有商品ID字段,单据2的商品表中也有商品ID字段,如果不拉出外键的话,当单据1,2都使用商品ID为3的商品后,删除此商品后,再查看单据1,2的时候就会查不到商品的名称

当表很少的时候,有人认为可以在程序实现的时候来通过写脚本来保证数据的完整性和一致性,也就是在删除商品的操作的时候去检测单据1,2中是否已经使用了商品ID为3的商品,但是当你写完脚本之后系统有增加了一个单据3 
他也保存商品ID找个字段,如果不拉出外键,你还是会出现查不到商品名称的情况,你总不能每增加一个使用商品ID的字段的单据时就回去修改你检测商品是否被使用的脚本吧

第二点就是增加ER图的可读性。这也同样是在后台数据库表非常多的时候能够体现出来的,外键能够明确的两个表之间的关系,例如一个单据的主表和单据的品的子表,如果两个表没有拉出外键表明关系,且两个表的位置在ER图中很远,对于一个对这个系统不是非常了解的人来说,让他去理出两个表之间的关系是很麻烦的,如果你拉出外键就算两个表离的很远,他也能随着外键找出他们之间的关系来,ER图的可读性对于一个刚刚接触大型系统的新手来说是极为重要的。

当然,外键的个数也不是没有个尺度,因为外键拉的过多会使ER图极为混乱(到处都是线) ,所以应该掌握合适的尺度才行,必要的外键必须要拉出来。如果实在不想因为外键过多而造成ER图的混乱,可以对基础数据的删除用假删除的办法,以避免在没有外键约束和检查的情况下造成数据的不一致性。

转载: http://blog.csdn.net/dowson2002/archive/2007/08/29/1764148.aspx

uniqueidentifier数据类型

uniqueidentifier数据类型可存储16字节的二进制值,其作用与全局唯一标记符(GUID)一样。GUID是唯一的二进制数:世界上的任何两台计算机都不会生成重复的GUID值。GUID主要用于在用于多个节点,多台计算机的网络中,分配必须具有唯一性的标识符。 在SQL中 ROWGUIDCOL表示新列是行的全局唯一标识列。对于每个表只能指派一个uniqueidentifier 列作为ROWGUIDCO列。ROWGUIDCOL属性只能指派给uniqueidentifier列
一 什么是uniqueidentifier?
Uniqqueidentifier 是全局唯一的标识

p d [3~)F F C E0二 UniqueIdentifier    数据类型的列如何赋值?
       1 使用 NewID()函数 来实现
       2 直接将字符串的常量转化成这样的格式 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
       举例:6F9619FF-8B86-D011-B42D-00C04FC964FF 为有效的UniqueIdentifier数据
       3 直接赋于32位的十六位数据
       举例 0xffffffff00000000ffffffff00000000
三 UniqueIdentifier 数据类型 数据实际是怎么在数据库中保存的?
UniqueIdentifier 数据类型存储实际的数据是16个字节的二进制值,
UniQueIdentifier 可以转化成实际的字符串型和二进制数据类型

四 NewID()函数是如何生成唯一的UniqueIdentifier 值的呢?
NewID()函数是从他们的网卡上的标识数字和CPU时钟的唯一的数字生成新的UniqueIdentifier数据 ,这个数据和GUID是一样的每台计算机能生成全球唯一的值
这样在多台计算机和多网络之间生成具有唯一性的标识符

五   使用 Uniqueidentifier数据类型的主要的优点
     Uniqueidentifier 数据类型主要的优点是在使用newid函数生成值的时候是可以保证值的全球唯一性
     可以唯一的标识单行的记录 对于多库(尤其是多机器,多网段的数据库的复制)来将比IDEntity来的更有效
     其次在使用Identity的情况下,我们对自动生成的值是不能修改的,而Uniqueidentifier数据类型是可以随时修改的
     
六   使用Uniqueidentifier的数据类型的缺点
1 对于生成的Uniqueidentifier 类型的值来讲 ,是无序
            在正常显示相关的数据信息的时候,返回的信息是无序的ITPUB个人空间 p e%A _0`2I l(G!v t0]
            对于 Identity 为标识的数据显示的时候,默认的情况下是根据添加记录的顺序来显示的。这样,对于uniqueidentifier为主键的信息集 ,还是需要一个默认标识排序的字段。
      
2 对于Uniqueidentifier 字段来将数据的实际的信息为16个字节,相对来将比Identity来讲 大的多,相对来将 存储空间和查询的效率会降低很多的。

七   在系统数据库的设计中我们如何对Uniqueidentifier,Identity ,和可标识的记录属性(有实际的含义的信息)作为主键 ,这三种方式 进行取舍
      
         以属性为主键的系统设计情况
      在系统设计的过程中
         单条信息中包含可以表示唯一性的属性(一般不能太多3个以内)而且这样的属性是必填字段。在记录生存周期内一般是不进行改动的,表一般多于50个这样级别的系统
     以属性为主键 ,这样的方式还是最佳的

    举例: 关于学生的管理信息系统 以学生的学号为主键

    以Uniqueidentifier 列为主键的情况
    在需要多个数据库之间,多个网段之间需要进行数据库的复制时,我们就需要在每一个唯一的标识来区别每一个单条记录,在没有合适的属性来做主键的情况下可以用Uniqueidentifier列来生成主键

    以 Identity为主键的情况
    不需要数据库的复制,和系统比较小的情况下(50表以内)可以用 Identity列来生成主键,适合于快速开发

作者:amzkqi 发表于2013-12-22 18:34:40 原文链接
阅读:164 评论:0 查看评论

相关 [主键 外键] 推荐:

主键和外键的作用

- - CSDN博客数据库推荐文章
主键和外键是把多个表组织为一个有效的关系数据库的粘合剂. 主键和外键的设计对物理数据库的性能和可用性都有着决定性的影响. 必须将数据库模式从理论上的逻辑设计转换为实际的物理设计. 而主键和外键的结构是这个设计过程的症结所在. 一旦将所设计的数据库用于了生产环境,就很难对这些键进行修改,所以在开发阶段就设计好主键和外键就是非常必要和值得的.

外键和锁

- - CSDN博客数据库推荐文章
使用外键是需要付出代价的,也就是, 即时检查,逐行进行,当然Oracle有个延时检查. 要求每次修改时都要对另外一张表多一次select操作,使用select lock in share mode方式. 意味着需要额外的锁,来确保该记录不会在事务未完成前被删除. 这将导致更多的锁等待,甚至是死锁,因为关联到其他表,死锁很难被爬出.

hibernate insert 时 无主键使用复合主键

- -
复合主键,由多个字段组成主键,例如,使用一个用户的firstname和lastname组成主键. 可以通过两种方式确定主键,一种是基于实体类的复合主键,另一种是通过定义主键类来实现. 不管通过哪种方式,复合主键都需要实现equals方法和hashcode方法,以作为不同数据之间是别的标志. 一.基于实体类属性的复合主键.

分库设计中的主键选择

- Epile - zolazhou.com
在先前的文章《又拍网架构中的分库设计》中, 我有提到过MySQL分库设计中的主键选择问题. 在这篇文章里我想对这个问题进行展开讨论, 以此作为对上一篇文章的一个补充. 前面提到又拍网采用了全局唯一的字段作为主键. 比如拿照片表为例, 虽然不同用户的照片数据存放在不同的Shard(或者说MySQL节点/实例, 请参考《又拍网架构中的分库设计》)上, 但是每一张照片拥有整个站点唯一的ID作为标示.

注解 主键生成策略

- - CSDN博客推荐文章
一、JPA通用策略生成器 . 通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, . 其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, . JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出. .

hibernate annotation 之 主键生成策略

- - BlogJava_首页
Hibernate 默认总共支持 13 种生成策略 :. 下面介绍几个较为常用的策略 :. ① identity [ 自然递增 ].          支持 DB2,MySQL,SQL Server,Sybase 和HypersonicSQL 数据库, 用于为 long 或 short 或 int 类型生成唯一标识.

sql中,如何得到新增数据的id(主键自增)

- - CSDN博客推荐文章
我们在项目中常常遇到这种情况,想得到刚刚新插入数据库那条记录的id,语法如下:. 执行后返回id,然后可以把这个sql当做查询语句执行,得到返回的id. 作者:zhujianpengzha 发表于2012-11-3 19:06:31 原文链接. 阅读:33 评论:0 查看评论.

使用递归唯一性验证的方式生成主键

- - CSDN博客数据库推荐文章
JadePool作为简化JDBC编程工具,提供 主键生成方法是必须的. 在JadePool中,ProcessVO用于事务型数据库的DML操作,Access用于非事务型数据库的DML操作,Access参照ProcessVO实现. 目前,JadePool只提供了单主键的键值生成方法,没有提供复合主键的生成方法.

InnoDB一定会在索引中加上主键吗

- - OurMySQL
DBA群里在讨论一个问题,到底InnoDB会不会在索引末尾加上主键,什么时候会加. 我之前看代码记得是如果索引末尾就是主键,那么InnoDB就不再添加主键了,如果索引末尾不是主键,那么会添加主键,但是这跟测试结果不符:. 插入部分数据后可以看到idx1和idx2两个索引的大小相同. 这说明idx1和idx2的内部结构是一样的,因此 不可能 是idx1在内部存为(a,b,a).

深入理解Redis主键失效原理及实现机制

- - NoSQLFan
本文来自@ 梁喜健 的热心投稿,原文见作者的 新浪博客,对于 缓存失效,不同的缓存有不同的处理机制,可以说是大同中有小异,作者通过对 Redis 文档与相关源码的仔细研读,为大家详细剖析了 Redis 的缓存过期/失效机制相关的技术原理与实现细节. 作为一种定期清理无效数据的重要机制,主键失效存在于大多数缓存系统中,Redis 也不例外.