SQL反模式学习笔记22 伪键洁癖,整理数据

目标:整理数据,使不连续的主键Id数据记录变的连续。

反模式:填充断档的数据空缺。

  1、不按照顺序分配编号

          在插入新行时,通过遍历表,找到的第一个未分配的主键编号分配给新行,来代替原来自动分配的伪主键机制。

          使用Select Max(Id) + 1 这种查询语句,会出现并发访问的问题。

  2、为现有数据行重新编号:通常做法是找到主键最大的行,然后用最小的未被使用的值来更新它。

    缺点:(1)SQL语句比较麻烦;

         (2)必须同时更新所有引用了你重新分配了主键的行的子记录;

       (3)无法避免产生新的断档。

  3、制造数据差异

    如果别的外部系统依赖于数据库中的主键来定义数据,那么你的更新操作就会导致那个系统中的引用失效。

    重用主键不是一个号的注意,因为断档往往是由于一些合理的删除或者回滚数据所造成的。

    别因为那些伪键看上去是没用的而重新分配他们。

 

如何识别反模式:当出现以下情况时,可能是反模式

  1、在我回滚了一个插入操作后,要怎么重用囊而自动生成的标识?

          伪键一旦生成后不会回滚。如果非要回滚,RDBMS就必须在一耳光事务的声明周期内生成一个伪键,

          而这在多个客户端并发地插入数据时,会导致竞争或者死锁。

  2、bugId为3的这条记录怎么了?

  3、如何找到第一个未使用的Id?

  4、自增长整形id的数字标识如果达到了最大值怎么办?

 

合理使用反模式

  没有理由要去改变伪键的值,由于它的值本身并没有什么重要的意义。如果这个主键列有实际的意义,那么这就是一个自然键,而不是伪键。

 

解决方案

  主键的值必须是唯一且非空的,因而你才能使用主键来唯一确定一行记录,但这是主键的唯一约束,

     他们不需要一定非得是连续值才能用来标记行。

  1、定义行号:使用Row_Number()或者Limit等关键字来实现;

  2、使用Guid:数据库全局唯一标识符。

          优点:(1)可以再多个数据库服务器上并发地生成伪键,而不用担心生成同样的值。

                  (2)不存在断档的问题。

          缺点:(1)Guid的值太长,不方便输入;

       (2)Guid的值是随机的,因此找不到任何规则或者依靠最大值来判断哪一行的最新插入的;

       (3)Guid的存储需要16字节,这比传统的4自检整形伪键占用更多的控件,并且查询的速度更慢

 

结论:将伪键当做行的唯一性标识,但它们不是行号。

 

 

SQL反模式,系列学习汇总

1SQL反模式学习笔记1 开篇

2、SQL反模式学习笔记2 乱穿马路

3、SQL反模式学习笔记3 单纯的树

4、SQL反模式学习笔记4 建立主键规范【需要ID】

5、SQL反模式学习笔记5 外键约束【不用钥匙的入口】

6、SQL反模式学习笔记6 支持可变属性【实体-属性-值】 

7、SQL反模式学习笔记7 多态关联

8、SQL反模式学习笔记8 多列属性

9、SQL反模式学习笔记9 元数据分裂 

10、SQL反模式学习笔记10 取整错误

11、SQL反模式学习笔记11 限定列的有效值

12、SQL反模式学习笔记12 存储图片或其他多媒体大文件

13、SQL反模式学习笔记13 使用索引

14、SQL反模式学习笔记14 关于Null值的使用

15、SQL反模式学习笔记15 分组

16、SQL反模式学习笔记16 使用随机数排序

17、SQL反模式学习笔记17 全文搜索

18、SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题

19、SQL反模式学习笔记19 使用*号,隐式的列 

20、SQL反模式学习笔记20 明文密码

21、SQL反模式学习笔记21 SQL注入

22、SQL反模式学习笔记22 伪键洁癖,整理数据

 

posted @ 2014-10-17 16:57  张传宁  阅读(736)  评论(0编辑  收藏  举报
页脚 HTML 代码