2011-08-24 53 views
0

我被要求使用一个数据库,其中大多数主键和其他字段也使用char(n)来存储带有填充的数值,例如:MySQL:使用char(n)与使用零填充的十进制(n)

product_id: char(8) [00005677] 
user_id: char(6) [000043] 
category_id: char(2) [05] 

他们想用它这样的原因,是为了能够使用的字符(在遥远的未来),如果他们想要的。然而,他们有许多基于数字的规则,例如,从01到79的category_id对应于一般类别,并且从80到89是特殊类别,而90到99是用户定义的类别。

我个人认为使用char(n)来存储数字是一种不好的做法。我的理由是:

  1. 使用char,“”!= 0,0!= 00,05!= 5,00043!= 000043等等。因此, 的值必须经常检查(以防止数据损坏)。
  2. 如果我垫了一些:0 - > 00,那么我要注意不要垫 字符(A - > 0A)
  3. 如果使用的字符,然后范围变得怪怪的,是这样的: 从01〜79和AB和RX和TZ和S,等...
  4. 索引号代替字符导致性能增益

我提议将其改为十进制(N)与ZEROFILL到使其更加“防错”,因为这些信息被不同的来源(网络,Windows客户端,上传CSV)修改。例如,如果他们想要添加更多类别,那么从小数点(2)更新为小数点(3)会更容易。

我的问题是:我错了吗? char(n)可以被这个任务信任吗?如果“字符”是邪恶的数字,那么我在上面的列表中缺少哪些其他缺点(如果我想赢得我的情况,我可能需要更好的理由)?

TIA(任何评论/答案将不胜感激)。

+0

我会接受谁能说服我的答案,使用char(n)这种方式是完全安全的,或者可以给我更多理由说明为什么不使用char。 – lepe

+2

@lepe:基于“最佳实践”,案件本身是荒谬的。领先的零与存储无关,但只与演示有关。只要您希望您的ID以前导零显示 - 请在**之前将它们**输出给用户,并以您喜欢的任何格式进行存储。 – zerkms

+0

+1。我完全同意你...恕我直言,突然使用chars通常只有数字被使用可能会打破未来的事情。唯一的原因是他们想记住字符的数量(这是:99,AA(2个字符); 100(3个字符))。但我认为这不值得复杂化。如果有必要的话,增加数字只是更容易......但向他们解释! :S – lepe

回答

1

如果这是SQL Server或Oracle或任何其他RDBMS,我会建议执行这些列的检查约束,使数据总是匹配列的全部容量 - 这将确保您的标识符是统一的。

不幸的是MySQL doesn't support this

虽然它不会阻止对进入数据库或搜索例程,客户端或数据库中的procs的事物进行填充的烦恼,但它可以保证字段在最低级别上是干净的。

我发现使用这样的约束有助于避免事情变得非常失控。

就使用数字进行优化而言,如果它们在将来需要容纳非数字字符,那不会是一种选择。

使用varchar/char数据拥有自然键(可能是主键的候选对象)是非常普遍的,但是却改为对替代键实施参照完整性(通常是某种自动编号整数,它只是一个内部参考,并且通常是聚集索引和主键)。

+0

是的,使用触发器来填充数据可能是一个选项... CHECK可以让我的生活更轻松,我猜...但我坚持使用MySQL。 因此,基本上你说过,如果没有这些CHECK,你的数据可能会非常失控?很久以前,我提出使用内部的AUTOCOUNT引用,但他们拒绝这个想法,因为数据的一部分直接从每个Windows客户端导入,他们认为这会让它复杂化。 – lepe

+1

@lepe如果你无法在数据库中执行它,任何事情都可能发生。我总是想知道数据库在它暴露给消费者的周边(表格/视图或特效)时能够保证的服务/完整性。为了减轻它不作为声明性约束,你可以有一个每小时/每天的过程,检查潜在的问题,并将它们扼杀在萌芽状态。使用数据库元数据编写/编码生成和保持更新将会相对容易,并为您提供更好的信心。 –

+0

+1确切地说,“如果你不能在数据库中执行它,任何事情都可能发生”:这是我需要扩展的想法。在我无法说服他们的情况下,运行cron来检查数据也是一个不错的主意,我会考虑这一点。 – lepe

1

引用你的问题:

...存储与填充数值...

你没有表现出数字数据,只是恰好包含数字的字符数据的任何实例。如果你说他们的OrderTotal列是char(10),那么我会开始担心。

只是把它当作字符数据,你会没事的。我看不到任何业务或技术案例来更改数据库(除非您开始接近完全重写)。

关于性能......如果这是实际上担心,那么你很可能有更大的问题需要处理。 MySQL是快速和准确的。

-

写一个函数的地方,将ZEROFILL用户输入ID的查询的目的。使用此功能无处不在您需要接受用户输入。永远不要使用数字数据类型来存储你的数据(如果PHP,从来没有使用+,总是使用.来连接,等等......)

请记住,这是没有区别Item_Number = "SHIRT123"或任何其他您可能遇到的字符串ID。

以关心

+0

是的,还有其他字段(如OrderTotal),其中使用int ...没有问题。数据库本身很旧(可能是8岁),但是系统完全从零开始改写,无论是web还是windows客户端,系统还没有启动,所以还是有时间来提出一些改变,我主要关心的是数据完整性,并减少错误的可能性,因为它会被数百个分支机构使用。 – lepe

+0

“只要把它当作字符数据,你就会好起来的,我不会看到任何改变数据库的商业或技术案例”:问题在于我不是唯一的开发者,如果有人想检查填充何时是一个数字),那么你正在添加损坏的数据。正如Cade评论的那样,如果可能的话,我想在数据库中执行它(因为数据在不同的客户端被修改)。 – lepe