Sql 负整数索引:它们是邪恶的吗?

Sql 负整数索引:它们是邪恶的吗?,sql,database-design,indexing,Sql,Database Design,Indexing,我有一个我正在设计的数据库 它需要包含几十个表,其中包含我们提供的记录(一组默认值)以及用户可以添加的记录。为了防止用户开枪打中自己的脚,有必要防止用户修改默认记录 有很多方法可以帮助实现这一点,但我喜欢这样的想法:为受保护的记录提供负整数索引,同时将0保留为无效记录id,并为用户记录提供正整数索引 CREATE TABLE t1 ( ixt1 integer AUTOINCREMENT, d1 double, CONSTRAINT pk_ixt1 PRIMARY

我有一个我正在设计的数据库

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

有很多方法可以帮助实现这一点,但我喜欢这样的想法:为受保护的记录提供负整数索引,同时将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
创建表t1(
ixt1整数自动递增,
d1双倍,
约束pk_ixt1主键(ixt1),
约束通道零点检查(ixt1 0)
);

-2 | 171.3我在一个非常大的计费系统上工作。我们有一个非常相似的问题。。。需要将某些记录标记为“特殊”。对于受影响的表,客户的数据库中有数千万行的现有数据,将所有这些数据迁移到新结构(即添加列)是不可接受的

决定完全按照你的建议去做

问题是,您需要了解(并记住)负指数的特殊含义,并正确处理它。这很容易出错(从经验上讲)


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

这其中最重要的缺陷是“智能钥匙”问题

负整数可以很好地用作键。在所有数据库中

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

这相对容易搞砸,因为指数有一个“规则”,并不明显,在你中了彩票离开后,没有人会记得

此外,当你发明第三种状态代码(“预罐装”与“客户特定罐装”与“由产品线发明的另一种罐装”与“第三版之前的旧罐装”)时,你注定要失败

“智能钥匙”的问题是,你要求钥匙做两个不相关的工作

  • 它是记录的唯一标识符。这就是钥匙应该是什么

  • 您还要求它提供状态、控制和更改属性的授权。哎呀。这充满了危险。你不能扩展它的含义,因为它是隐藏在密钥中的一个位

  • 只需添加一列“owned by”。如果它属于“神奇超级用户”,则不会向用户显示。如果您不能信任您的应用程序开发人员来实施它,请使用视图来确保这一点


    如果它属于“神奇超级用户”,那么它是默认数据,以及适用于该所有权的任何规则。

    它是您的数据,但我认为这不是一个好主意。像这样的“索引”值应该是没有意义的-不要使用符号或数字范围或任何表示“某物”或“其他某物”的东西。我认为,从长远来看,你最好有一个“记录类型”栏,清楚地表明你在看什么样的记录。根据我的经验,这是一个更好的方法


    祝你好运。

    我注意到你的主键上有
    自动递增
    ,这对你的策略有什么影响?您是为所有新记录手动计算正确的主键,还是仅为私有(负)记录手动计算正确的主键?只会显式设置私有(负)键。顺便说一句,我不知道这种特殊的SQL语法在任何DBMS上都有效。这只是为了说明。+1表示“所有业务逻辑都必须了解其特殊含义”。我真的很感激这是来自经验。但在我看来,就难度而言,增加一列就相当于增加一列。如果您添加了一个额外的列而不是使用负索引,那么您的代码会有什么不同?我认为最大的问题是开发人员(包括现在的开发人员,以及5年来在您有更好的工作时维护此功能的开发人员)期望将特殊含义建模为一列,而不是对索引的数值应用特殊解释。其他人也指出,如果将来需要额外的“特殊”含义,这种设计将无法扩展,因此人们必须检查索引的符号,如果有任何新的状态,则必须检查一列。因此,使用这种方法将降低软件的可维护性。我也相信这个论点,特别是因为你不得不处理另一个选择。让钥匙做两件事+1。一把钥匙就是一把钥匙,这就是它所需要的一切。通过添加其他列使行变得特殊。这不是个好主意。负整数索引不是坏事,但您的设计并不明显。可能是“容易理解”。但是从模式中很明显的是,没有。最好有一个名为is_canding或is_protected的布尔/位列。数据库中任何声明为“boolean”的内容都将变形为多个值。布尔值永远不应该被看作是一个持久的、描述性的属性;这是一个基于属性的条件,但不是一级属性。因此,这里的基本论点是,让键做两件事是一个坏主意,因为它不可扩展,而且是意外的。我相信这一点;这就是为什么我想用整数键而不是uuid。但我还是有点难过,因为我放弃了,而沾沾自喜于那个额外的专栏。使用正负键非常简洁,并且可以很好地细分表。似乎它应该是/something/的优雅解决方案“简洁”==代码气味。当实现隐藏在另一个对象的值中时,要非常小心简洁。当你在Don Knuth写一个可以被证明是最小值的算法时,这没关系。但是你的问题(我是谁