繁体   English   中英

数据库设计 - 硬编码行ID

[英]Database Design - Hard Coded Row ID

每个人都会将代码枚举与数据库表中的行ID联系起来? 我真的在寻找更清洁的选择。 例如,如果给定表中的静态行是ID的1,2,3,然后该表使用ID 4-100填充用户事务数据,然后您想在本地添加新的行ID生产数据库是行ID 4,但是当该行转到客户数据库时,它必须是101 ......那有点打破了一切。

那么如何处理表中的静态锁定行,这些行也充满了事务数据?

谢谢,MeshMan

不要那样做。 ;-)

如果你的静态行,永远不会改变的值,在具有事务性或至少是可变的用户数据的表中,那么我会说你在模式中至少有一个规范化问题。

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

我经常玩弄从DB表生成“源代码”Enum类或者在构建/部署时使用Enum类信息填充数据库表的想法,但我从来没有“理解它”。

不要在应用程序中将特殊逻辑基于数据库中的行ID,特别是如果您无法完全控制该表中的内容。 (我承认我有时会为查询表执行此操作,我绝对不会知道这些更改,但即使在这里也可能是不好的做法。)

如果你需要标记某些特殊记录,那么请放置一些表示该标志的“flag”字段,然后查询该标志。

我同意Stephen W.一个好的解决方案是使用ENUM项目的字符串name 我一直在.Net中使用这种方法,它很容易使用。

这个想法是,无论你的枚举有什么价值(并且无论数据库记录有什么ID),枚举名称只会在你的开发人员更改时改变。 与自动递增的ID号(在您的控制之外)相比,这是一种更易于管理的情况。 另外,阅读代码的其他开发人员知道名称试图描述的内容,而不是一些可能意味着任何东西的明显随机数,并且很可能意味着跨不同数据库的多个事物!

这可行的一种方法是让您的表具有文本代码或描述标识列。 这可能是一个字母数字值,但关键是它应该唯一地标识该记录。 实际上,这可以用作主键,但实际上我总是有一个自动递增的主ID号列。 这样一个表上的列示例:

PK_ID | CODE | Other Data PK_ID | CODE | Other Data

这里,代码字段的值实际上是您的枚举名称。 这是一个不需要更改的代码。 您必须在自己和您的团队中规定这些规则不要改变,但如果有人需要更改它,那么请确保它在两个平台上得到反映。

使用.Net处理Enum(在本例中称为SortDirection):

' 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)

它不是一个完美的解决方案,但它对我很有帮助; 我已经被硬编码的ID太多次困惑和烦恼,以至于不能更好地理解这两个邪恶。 希望有所帮助!

我同意Ken G - 对应于行ID的枚举值仅对具有静态(不变)内容的查找表有意义

也许您可以发布一个示例来帮助我们更好地理解,但如果您有一些被指定为“系统”条目的行,您可以考虑在名为Order的表中添加一列,然后在创建一个专门设计的条目时作为系统条目,您可以增加Order列。

对于大多数其他内容,例如查找表,您应该能够更明确地控制行ID并使用它们。

嗯,一个枚举应该是一个常数 - 你不希望改变的东西 - 你真的不能说数据库中的数据。

无论如何,你的问题来自于你从ENUM文本后面的INTEGER保存/加载的事实。 这里有用的解决方案是从枚举的TEXT值进行查找/保存/等

这个VB代码将字符串转换回ENUM,它应该很容易移植到C#:

[Enum].Parse(System.Type, Value)

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

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

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

永远不应该存储ROWID,因为它们可以改变。 如果您将其中一个表移动到新的表空间,则所有存储的ROWID都将变为无效(无论如何,这在Oracle中都是如此)。

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

不判断你的计划的合理性。 DBA和其他人总是喜欢说,“不要这样做。” 好像你问你是否应该这样做,即使你没有问过,就像你可以选择不这样做。

我会假设你问了你的问题是有原因的,你没有选择不这样做。

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

在Oracle中,您可以创建序列以填充自动编号字段。 序列完全独立于表格。 您可以在多个表中使用一个序列,您可以在一个表中使用多个序列。 如果我必须解决你的情况,我会创建2个序列,一个从1开始,一步一步(对于管理数据),一个从2开始,逐步2(对于用户数据)。 我将更改我的插入过程以使管理插入的选项参数拉出正确的序列。 您永远不会碰撞您的数据和用户数据。 基于ID的奇偶校验能够区分两者的副作用。 缺点是存在硬限制。

我必须先在状态表上执行此操作。 在安装应用程序时,必须始终存在某些“内置”值,并在特定时间点进行特殊处理。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM