Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 数据库设计-硬编码行ID_Database_Database Design - Fatal编程技术网

Database 数据库设计-硬编码行ID

Database 数据库设计-硬编码行ID,database,database-design,Database,Database Design,将代码枚举绑定到数据库表中的行ID时,每个人都会做些什么?我真的在寻找一个更干净的替代品。例如,如果给定表中的静态行是ID的1,2,3,然后该表使用ID的4-100填充用户事务数据,然后您想添加一个新的行ID,该行ID在本地生产数据库中为行ID 4,但当这一行进入客户数据库时,它必须是101…这有点破坏了一切 那么,如何处理表中的静态锁定行,该表中也会充满事务数据 谢谢, 梅斯曼不要那样做 如果在一个包含事务性或至少可变的用户数据的表中有静态行和永不更改的值,那么我认为模式中至少存在一个规范化问

将代码枚举绑定到数据库表中的行ID时,每个人都会做些什么?我真的在寻找一个更干净的替代品。例如,如果给定表中的静态行是ID的1,2,3,然后该表使用ID的4-100填充用户事务数据,然后您想添加一个新的行ID,该行ID在本地生产数据库中为行ID 4,但当这一行进入客户数据库时,它必须是101…这有点破坏了一切

那么,如何处理表中的静态锁定行,该表中也会充满事务数据

谢谢, 梅斯曼不要那样做

如果在一个包含事务性或至少可变的用户数据的表中有静态行和永不更改的值,那么我认为模式中至少存在一个规范化问题

参考数据通常属于它自己的表。如果表本身只包含引用数据,那么从应用程序分配ID或使用从DB生成的ID将成为首选


我经常想从DB表生成“源代码”枚举类,或者在构建/部署时用枚举类信息填充DB表,但我从来没有“着手过”。

也许您可以发布一个示例来帮助我们更好地理解,但是如果您有一些行被指定为“系统”条目,您可以考虑将一个列添加到名为Orror的表中,然后,当您创建一个被设计为系统条目的条目时,可以递增订单列。
对于大多数其他事情,如查找表,您应该能够更明确地控制行ID并使用它们。

我同意Ken G的观点-只有在具有静态(不变)内容的查找表中,枚举值对应行ID才有意义,枚举应该是一个常量——这是您不希望更改的内容——对于数据库中的数据,您确实不能这样说

无论如何,您的问题来自这样一个事实:您正在从枚举文本后面的整数保存/加载数据。在这里,一个有帮助的解决方案是从枚举的文本值进行查找/保存/etc

这段VB代码将字符串转换回枚举,移植到C#应该很容易:


不要将应用程序中的特殊逻辑建立在数据库中的行ID上,尤其是当您无法绝对控制该表中的内容时。(我承认我有时会对我绝对知道不会改变的查找表这样做,但即使在这里,这也可能是一种不好的做法。)


如果您需要标记某些特殊记录,那么请放置某种类型的“flag”字段来指示这一点,并改为在该标记上查询。

这里有一个解决方案:大多数数据库都有一种机制来生成新的ID值,该值从1开始,正向递增

但是,如果主键列是有符号整数,则可以对静态行使用负值。ID为-1表示'--NONE--',ID为-2表示'--SPECIAL--'或其他任何形式。如果需要更多静态行,请向负方向前进


如果外键也是有符号整数,则外键仍然可以引用静态行和用户生成的行。

不应存储ROWIDs,因为它们可以更改。如果将其中一个表移动到新表空间,所有存储的rowid都将无效(无论如何,在Oracle中也是如此)


如果您有一个用于FK目的的特殊行需要保护,您可以使用触发器防止其被更新。

不判断您的计划的合理性。DBA和其他人总是喜欢说,“ 就好像你问自己是否应该这样做,即使你没有问,就像你有选择不去做一样

我假设你问这个问题是有原因的,你没有选择不这样做的余地

我有一个朋友认为Oracle序列很痛苦,自动编号字段要容易得多。它们不是那么“容易”,但它们更灵活。到目前为止,你还没有说明你的平台,所以没有mod-1请


在Oracle中,您可以创建序列来填充自动编号字段。序列完全独立于表。可以在多个表中使用一个序列,也可以在一个表中使用多个序列。如果我必须解决您的情况,我会创建两个序列,一个从1开始,按2步执行(对于管理员数据),另一个从2开始,按2步执行(对于用户数据)。我会更改我的插入过程,为管理员插入提供一个选项参数,以提取正确的序列。您的数据和用户数据永远不会发生冲突。能够根据ID的奇偶性来区分两者有一个副作用。缺点是有一个硬限制。

我以前不得不在状态表上这样做。安装应用程序时,某些“内置”值必须始终存在,并在特定时间点进行特殊处理

然后,用户可以出于工作流的原因创建自己的工作流

你能做的就是在1001开始你的序列。1到1000之间的任何值都是“内置”值。当然,1000在这里是一个神奇的数字,但在我的例子中,我只有5个内置值,所以看起来很安全


另一个选项是大于零的ID是用户创建的,小于零的ID是系统内置的。

我同意Stephen W的观点。一个好的解决方案是使用枚举项的字符串
名称
。我在.Net中一直使用这种方法,而且很容易使用

其思想是,无论枚举的值是多少(也不管数据库记录的ID是多少),只有当开发人员更改枚举名称时,它才会更改。与自动递增的ID号(您无法控制)相比,这是一种更易于管理的情况。阅读您的代码的其他开发人员也知道w
[Enum].Parse(System.Type, Value)
' Get the string name of an enum
[Enum].GetName(GetType(SortDirection), SortDirection.Ascending)

' Get the enum value from its string name
CType([Enum].Parse(GetType(SortDirection), "Ascending"), SortDirection)