负整数指数:它们是邪恶的吗?

Mat*_*owe 4 sql indexing database-design

我有这个我正在设计的数据库.

它需要包含几十个表,其中包含我们提供的记录(一组默认值)以及用户可以添加的记录.为了防止用户在脚中射击自己,有必要让他不要修改默认记录.

有很多方法可以促进这一点,但我喜欢给予受保护记录负整数索引的想法,同时保留0作为无效记录ID并给予用户记录正整数索引.

CREATE TABLE t1 (
    ixt1  integer AUTOINCREMENT,
    d1    double,
    CONSTRAINT pk_ixt1 PRIMARY KEY (ixt1),
    CONSTRAINT ch_zero CHECK (ixt1 <> 0)
);

-2 | 171.3 <- canned record
-1 | 100.0 <- canned record
 1 | 666.6 <- user record
Run Code Online (Sandbox Code Playgroud)

原因似乎很好:

  • 它不会占用更多的空间

  • 这很容易理解

  • 它不需要很多额外的表来实现

  • "select*from table"获取所有相关记录,没有额外的间接

  • 固定记录可以向负方向增长,用户记录可以向正方向增长

但是,我对数据库设计比较陌生.在使用这个解决方案一段时间之后,我开始担心使用负面索引可能会很糟糕,因为

  • 不同DBMS之间可能不一致地支持负索引,这使得编写与数据库无关的代码变得困难

  • 通过在recid 0处插入一些东西来搞砸东西可能太容易了

  • 它可能使得很难使用期望具有非负值的整数索引的工具(例如db网格).

也许还有其他一些非常明显的原因会让这个想法变得非常糟糕.

那么最终的答案是什么呢?负整数指数是邪恶的吗?

S.L*_*ott 13

其中最重要的缺陷是"智能钥匙"问题.

负整数作为关键工作正常.在所有数据库中.

没有工具需要正整数索引值.

把它搞砸是相对容易的,因为索引有一个"规则",这个规则并不明显,在你赢得彩票并离开后没有人会记得.

此外,当您发明第三个状态代码('预先罐装'与'客户特定罐头'对比'由产品系列发明的其他罐头'与'旧罐头在版本3之前'')时,您注定要失败.

"智能密钥"的问题在于您要求密钥执行两个不相关的作业.

  1. 它是记录的唯一标识符.这就是键应该是什么.

  2. 您还要求它提供更改属性的状态,控制和授权.哎呀.这充满了危险.你无法扩展其含义,因为它只是隐藏在一个键中的一个位.

只需添加"拥有者"列.如果它由"魔法超级用户"拥有,那么它不会向用户显示.如果您不相信应用程序开发人员可以执行此操作,请使用VIEW确保这一点.

如果它由"魔法超级用户"拥有,则它是默认数据,并且适用于该所有权的任何规则.


Eri*_* J. 6

我在一个非常大的计费系统上工作.我们有一个非常类似的问题......需要将某些记录标记为"特殊".客户在其受影响的表的数据库中拥有数千万行现有数据,将所有数据迁移到新结构(即添加列)被认为是不可接受的.

决定采取你的建议.

麻烦的是,你需要每一点业务逻辑来了解(并记住)负指数的特殊含义并正确对待它.这很容易出错(从经验来讲).

除非你有非常强烈支持这种非传统方法的特殊情况,否则我建议你坚持使用更传统的额外专栏.这是大多数开发人员习惯的,因此不太可能导致错误.我希望我们会咬紧牙关并添加额外的列.