用于 sql 表中"Status"列的类型



我有一个(虚拟)表结构如下:

<>之前票id: int(11) PK:名字varchar (255) : ?????????之前

问题是,我应该使用什么数据类型的状态?以下是我看到的选项:

  1. 表示状态的varchar - BAD,因为没有完整性
  2. enum表示状态-坏,因为要改变值,我必须改变表,然后任何代码下拉的值,等等等等
  3. int FK到状态表-好的,因为它是动态的,坏的,因为很难通过视觉检查(这可能是有用的)
  4. varchar FK到状态表-好,因为它是动态的,并且在检查时可见。因为键是有意义的,这通常是不赞成的。有趣的是,在这种情况下,状态表完全有可能只有1列,使其成为一个美化的enum
我对形势有准确的了解吗?拥有一个有意义的密钥真的那么糟糕吗?因为虽然它确实让我起鸡皮疙瘩,但我没有任何理由这样做……

更新:对于选项4,建议的结构是status: char(4) FK,到状态表。

OPEN => " OPEN "

CLOS => "Closed"

" Pending Authorization" => "Pending Authorization"

"PROG" => "In Progress "

这种情况的缺点是什么?在这种情况下,我能看到的唯一好处是使用int而不是char。

我会选择第4列,但我会使用char(x)列。如果您担心性能问题,char(4)占用的空间(或者有人会认为是磁盘i/o、带宽和处理时间)与int一样多,后者也需要4字节来存储。如果你真的担心性能,把它设为char(2)甚至char(1)。

不要把它看作是"有意义的数据",把它看作是自然键的缩写。是的,数据是有意义的,但是正如您已经注意到的,在处理数据时,这可能是一件好事——这意味着您不必总是通过连接(即使连接到一个非常小的表)来从数据库中提取意义。当然,外键约束确保数据是有效的,因为它必须在查找表中。(这也可以用CHECK约束来完成,但是随着时间的推移,查找表通常更容易管理和维护。)

缺点是,你可能会陷入试图寻找意义。Char(1)具有很强的吸引力,但如果您有10个或更多的值,则很难想出好的有意义的值。char(4)的问题较少,但仍然可能存在问题。另一个缺点是:如果数据可能发生变化,那么是的,您的有意义的数据("PEND"="等待授权")可能会失去其意义("PEND"="转发到总部进行初步批准")。这是一个糟糕的例子;如果这样的代码确实发生了变化,那么重构系统以反映业务规则的变化可能要好得多。我想我的观点应该是,如果它是用户输入的查找值,代理键(整数)将是您的朋友,但如果它们是内部定义和维护的,您肯定应该考虑更人性化的值。否则你就需要在你的显示器上张贴便条来提醒你"Status = 31"应该是什么意思。(我的有三根,每隔几个月就会磨损一次。谈论维护成本…)

选择第3个。如果你想要一些可检查的东西,创建一个加入status值的视图。

我将使用INT,并创建到状态表的外键关系。对于枚举状态列来说,INT绝对是安全的。

我是否建议您使用statusID字段,并将ID映射到varchar的单独表?

编辑:我想这正是你在第三点概述的。我认为这是最好的选择。

我假设您的数据库具有某种描述的前端,并且普通用户不暴露于状态码。

所以,您的便利只适用于程序员和dba——重要的人,但我不会为他们优化我的设计。

更强——我会非常小心地使用"有意义的"缩写——我见过的最严重的数据混乱发生在开发人员清理一些数据时,错误地解释了"有意义的"键;原来"PROG"不是"编程"的意思,而是"正在进行中"的意思。

选择3。

我最近一直在使用很多数据库,这些数据库需要很多的状态,并且我有一些值得添加到对话中的注意事项。

INT:我发现的一件事是,如果应用程序正在进行大量跟踪,那么引用表的数量很快就会变得难以处理,并且,正如您所提到的,使得一眼检查数据库变得不切实际。(对于我的一些客户来说,这比在处理时间上节省的几毫秒要重要得多。)

VARCHAR:对于编程来说,这是一个糟糕的想法,但重要的是要考虑给定的状态是否真的会被代码使用,或者只是人眼使用。对于后者,您可以获得无限的范围,并且不必维护任何关系。

CHAR(4):使用描述性字符列实际上是一种非常好的方法。我通常只会在数值范围较低且明显的情况下才会考虑它,但这只是因为我认为这是一种非标准方法(可能会让新开发者感到困惑)。实际上,您可以像使用INT一样使用CHAR值作为外键,以获得可读性并保持性能奇偶性。

你不能做的一件事,我想念的是数学运算(如"<"one_answers">")。

INT Range:我尝试过的一种混合策略是使用INT,但为数字添加一定程度的语义。例如,

1-10 being for initial stages, 
11-20 being in progress, and 
21-30 being the final stages. 
60-69 for errors, rejections

这里的问题是,如果你发现你需要更多的数字,你是SOL,因为下一个范围已经被占用了。所以,我最终做的是(某种程度上)模仿HTTP响应:

100-199 being for initial stages, 
200-299 being in progress, and 
300-399 being the final stages. 
500-599 for errors, rejections
与简单的INT相比,我更喜欢

,虽然可以比CHAR更具描述性,但它也可以更少歧义。而"PROG"可能意味着许多事情,好的,坏的或良性的,如果我看到一些东西在500范围内,我可能不知道问题是什么,我将能够告诉你有问题。

当您希望在HTML表单中显示状态列表时,创建一个单独的状态表是一个好主意。您可以显示查找表中的详细描述,如果需求是这样的,它将帮助用户选择状态。

从开发的角度来看,我想把整数作为主键。如果您知道它不会超过限制,您可以通过使用小/小整数来优化它。

如果你使用缩写作为外键,那么你必须每次都考虑使它唯一,因为@Philip Kelley已经提到过它的一个缺点。

最后,如果愿意,可以声明表类型MYISAM。

更新:反映@Philip Kelley的意见,如果有太多的状态,那么最好使用整数作为外键。如果只有两个状态,那么可以使用abbr作为外键。

最新更新