一家大型国际公司部署了一个新的网络和MOTO(邮购和电话订单)处理系统.除此之外,您还负责设计订单和客户识别号码的格式.
您认为最好的格式是什么?请列出任何假设和考虑因素.
接受的答案
迈克尔哈伦的答案因选票最多而被选中,但请阅读其他答案和评论,因为他们让迈克尔的答案更加完整.
使用所有数字或所有字母.如果你必须把它混合起来,那么确保没有含糊不清的字符(Il1m,O0等).
显示/打印时,每隔3-4个字符放置一个空格,但要确保您的系统可以处理没有空格的输入.
编辑:要考虑的另一件事是有一个内置的方式来区分订单,客户等.例如,客户总是从10开始,订单总是从20开始,供应商总是从30开始,等等.
不要将任何可变的客户/订单信息编码到数字中!你必须假设一切都是可变的!
上述一些建议包括区域代码.公司可以搬家.您自己的公司可能会重新组织并更改自己对区域的定义.客户/公司名称也可以更改.
客户/订单信息属于客户/订单记录.不在ID中. 您可以稍后修改客户/订单记录.身份证一般用石头写成.
即使只是将生成号码的日期编码到ID中似乎也是安全的,但是假设生成数字的系统上的日期永远不会出错.再次,这属于记录.否则永远无法纠正.
不止一个系统会产生这些数字吗?如果是这样,如果您仅使用基于日期和/或序列号,则可能会出现重复.
在不了解公司的情况下,我会从这条道路开始:
标识数字类型的单字符代码. C为客户,R为订单(不要使用"O",因为它可能与零混淆)等.
生成号码的系统的标识符.该标识符的长度取决于这些系统的数量.
序列号,对于生成它的系统是唯一的.只是一个柜台.
随机数,以防止可猜测的订单/客户编号.只要您的偏执需要,就可以做到这一点.
一个简单的校验和.不是为了安全,而是为了进行错误检查.
将其分解为细分使其更具人性化,正如其他人所指出的那样.
CX5-0000758-82314-12是此方法生成的可能数字.这包括:
C:这是一个客户编号.
X5:生成号码的站点.
0000758:这是X5生成的第758个数字.在退出此站ID或站本身之前,我们可以生成1000万.或者不要用零填充,并且没有限制.
82314:这是随机生成的,导致1/100,000的机会猜测客户ID.
12:校验和.
仅使用数字的主要优点是可以使用10键更有效地输入它们.
该数字的长度应尽可能短,同时仍包含您希望编制的整个实体空间,并留有余地.这可能很棘手,应该考虑一下.在给定一组元素的情况下,一个小集理论可以为您提供可以访问的唯一键的数量.
说话时很自然地将数字分成两到四位数.通过以某种模式插入破折号,您可以"强制"客户以更有效和明确的方式重复它们.
例如,323-23-5344,当然是社会安全号码格式,有助于告知发言者在发出号码时暂停的位置.它还在编写数字时提供可视化描述,并且在复制数字时可以轻松进行比较.
我建议订购系统正确屏蔽输入,以便不需要随时输入破折号.这应该通过印刷表格进行,以明确期望应该输入什么.例如,每个数字的打印盒由打印的破折号分隔.
我不同意应该在这个数字中嵌入太多的信息,特别是如果这些属性可能会改变的话.例如,假设我们给出"323"这个"很好的顾客"的含义,但他们会以态度四次打电话.我们是否会将他们的客户密钥更改为"324","是一个混蛋"?如果他们在04区并将他们的公司搬到05区怎么办?
如果发生这种情况,您的选择将是在整个数据库中更新该主键,或者存在嵌入该键中的信息不再可靠的模糊性,从而将所有信息嵌入到可疑实用程序的键中.
最好将可能更改的属性存储为数据库中的单独字段,并使客户编号成为该客户唯一且不变的密钥.
以丹尼尔和迈克尔的问题为基础:如果分开的数字意味着别的东西,那就更好了.例如,我在一家公司工作,帐号如下:
XXXXXXXX-XXXXXXXX
第一组数字代表该地区,第二组代表该地区的市场.一旦你习惯了解来自哪些数字,就可以很容易地判断一个帐户所在的区域,甚至无需查看客户的帐户.
我在回答这个问题时做了几个假设; 有些是基于这样一个事实:它是一个大型的国际组织,有些是基于这种格式是针对两种不同的表类型的事实.
基于它是一个国际组织这一事实的假设:
每个区域可能需要独立运行 - 也就是说,区域A必须能够独立于区域B添加客户编号
每个地区可能使用不同的语言,以便世界各地的用户可以轻松输入标识符,最好只使用数字和空格.
基于以下事实的假设:将使用此格式的两个表:
这种格式可能超过列出的两个表使用,因此它应该能够处理任意大量的表.
有经验的用户应该能够根据编码到标识符本身的信息知道他们正在查看的标识符类型.
如果标识符在整个系统中是全局唯一的,那将是很好的.
注意事项:
对于全球公司,如果仅使用数字,则标识符可能非常长.我们应该尽可能地限制编码到标识符中的无关信息的数量.
标识符应在有限的范围内自我验证; 这是一个程序应该能够检测到大部分无效标识符而不需要查找任何内容.这意味着校验和.
建议格式: SSSS0RR0TTC
建议的格式尽可能简单,但并不简单:
C第一个(最右边)字符将是标识符中所有其他字符的校验和.一个简单的校验和就行了.这将消除所有打字错误的90%.如果确定这还不够,那么这可以扩展到2位数,这将消除99%的所有输入错误.
TT接下来的N位代表表格类型编号.没有表类型编号可以包含数字零.
下一个数字是零.此零将表类型编号与区域编号分开.
RR接下来的N位数是区号.没有区域编号可以包含零.
下一个数字是零.该零将区域与序列号分开.
SSSS接下来的N个数字是序列号.此数字可以包含零.
当按照惯例打印或键入时,每组四个数字由空格分隔.在内部它们没有分开,但这有助于用户正确地传输它们.
例子
假设:
客户表类型= 1
订单表类型= 2
US-Alabama的区域代码= 1
CA-Alberta的地区代码= 43
Ethopia的地区代码= 924
10 1013 - 阿拉巴马州的客户#1(3是校验和:1 + 1 + 1)
10 1024 - 在阿拉巴马州订购#1
9259 0304 3016 - 客户#925903在加拿大艾伯塔省
20 3043 4092 4023 - 订单编号2030434在Ethopia
这种方法的优点:
90%的错误数字将被捕获
有无限数量的表类型
有无限数量的地区
每个表都有无限数量的序列号
标识符号对于系统是全局唯一的.这很重要 - 客户编号不能被误认为是订单编号,反之亦然.
每个区域可以独立添加序列号而无需全局键
缺点
每个标识符至少为六个字符
表类型数字和区域编号不能包含零,因为零用于将序列号与区域编号从表类型编号分开.
尽可能长一些,但不能再做.每次我支付水费时,我都要输入我的20位客户号码和18位数的发票号码.值得庆幸的是,我的客户编号中的破折号将其分为两部分.
不要依赖于前导零.必须弄清楚我的发票号码中有多少个零是非常烦人的.以000000000051415432为例.他们的系统不会只识别51415432.
组数字在一起.如果你绝对需要使用长数字,那么四位数的块应该可以正常工作.
我永远不会在ID中使用用户信息.假设您使用客户姓氏的第一个字母后跟一些数字:例如,Thomsom可能是客户THOM-0001.只是,看起来你犯了一个错误,男人的名字是汤姆森而不是汤姆森.用户数据可以更正,ID永远不可修改.所以下次你在TOMS下看Tomson -...你找不到他.与其他数据相同,如客户类型.它总是可以改变,ID不能.
这对RDBMS来说非常基础.
只需使用计数数字.为了便于阅读,最好插入分隔符,使得从不超过4个连续数字:9999-9999优于999-99999.并且不要使数字超过必要的时间; 人们因为被减少到20位数而不仅仅被减少到一个数字而更加恼火.
但是有一个问题.特别是如果你有一个小企业,简单的柜台可以提供比你所欣赏的更多.说我订购了你的东西,订单号是090145.下个月我再次订购,订单号是090171.呃..一个月26个订单?同样,在一家活跃了10年的企业中成为客户0006我感到不舒服.
解决方案很简单:跳过数字.不要使用随机数,因为您仍然希望它们按顺序排列.
我的订单号会遵循以下格式:
ddmmyyyy-####-####
#### - ####在每天开始时重置为零.这使得将订单与其下达日期相关联变得非常容易.
对于客户ID,我会混合使用大写字母和数字,但正如Michael所说,避免使用通常错误的字母(0,o,L,1,5,s).这将给你30个字符来处理.如果您使用20个字符,那将为您提供几乎64位的客户ID - 非常有利于安全性.确保在生成ID时使用安全随机数生成器.至于如何显示格式,应该如下:
####-####-####-####-####
正如迈克尔再次说的那样,确保你的系统可以处理破折号,空格,没有空格或没有破折号.(它应该在验证之前从输入中删除所有这些字符.)
我希望有所帮助!
您可以添加一个小校验和(例如使用XOR)以确保(增强)给定ID的正确性.如果是通过邮件,请考虑z-base-32编码.但在这里,通过电话订单,您可能更喜欢小数识别.