我正在开发一个 winform (.NET) 应用程序,其中包括订单、发票、服务订单、票务等。
这些实体在编号它们的 ID 时有必要按顺序排列吗?国际海事组织编号 以订单为例,它只有在通过业务层时才有效,在此过程中,可能已经创建、批准并保存了另一个订单,编号为 2,而之前创建的 id 为 1 的订单未通过验证。
这似乎打开了一个关于哪个层分配订单号的蠕虫罐,不是吗?
目前我正在使用以实体标识符为前缀的非连续数字。例如,订单使用 OR-123。这是一个好主意吗?
谢谢
我正在开发一个 winform (.NET) 应用程序,其中包括订单、发票、服务订单、票务等。
这些实体在编号它们的 ID 时有必要按顺序排列吗?国际海事组织编号 以订单为例,它只有在通过业务层时才有效,在此过程中,可能已经创建、批准并保存了另一个订单,编号为 2,而之前创建的 id 为 1 的订单未通过验证。
这似乎打开了一个关于哪个层分配订单号的蠕虫罐,不是吗?
目前我正在使用以实体标识符为前缀的非连续数字。例如,订单使用 OR-123。这是一个好主意吗?
谢谢
如果它是有效的业务需求,您只需要具有顺序 ID。
连续数字不是必需的,并且在某些情况下是一个坏主意(在有安全意识的系统中,猜测是一个问题)。但是让 RDBMS 处理这个问题是相对常见的——大多数都支持IDENTITY
自动递增类型(尽管它在使用多个分布式主服务器时变得更加复杂)。当然,另一种选择是Guid
- 重复的可能性很小。
前缀方法对于快速识别数字非常方便 - 但您可以选择仅在 db 上方的层添加“OR-”。
会计和总账人员喜欢序列号,如果缺少数字,他们想知道原因。这是一种会计实践,如果不按照规格执行,可能会花费企业时间和金钱。
我认为我们应该区分技术 ID 和我们可以称之为文档 ID 的东西。可能会有法律要求。例如,在瑞典,我认为法律要求您的发票必须按完整的顺序显示发票编号。
但是,如果我要设计一个发票系统,我可能会选择一个与发票 ID 分开的技术 ID,最好没有任何逻辑(例如 Guid)。
根据我在美国使用现成和定制会计系统的经验,会计师或审计师不需要序列号。所需要的是控制和审计能力的证明。如果一个项目被删除,必须有一个踪迹。删除项目的检测不会通过丢失的数字来跟踪 - 毕竟,还有其他类型的篡改需要序列号来解决,而充分控制的演示远远不止于此。
但是,我在墨西哥看到了政府要求报销的这种要求。我相信他们使用它来避免向国家机构多次提交的欺诈行为。IMO,它不是一种有效的内部控制,并且在第三方互动情况下捕获欺诈的范围有限。
通常,使用增加的整数 id(如 IDENTITY)(或 GUID - 但普通 GUID 不会像那样增加)作为表中的代理主键和集群有助于提高 SQL Server 性能。请注意,可能会用完 IDENTITY 值,但事务可能会失败或回滚,从而留下空隙。这个空白通常不会被填补(尽管它可以通过使用身份插入来填补)。
以下是一些 COMB ID 链接:
http://www.informit.com/articles/article.aspx?p=25862
我们实际上对其进行了一些修改,将它们与 CSLA 一起使用,并将它们称为 SmartGUID。SmartGUID 类公开了创建日期属性。不幸的是,我不再隶属于那个项目或公司,所以我无法访问源代码来准确回忆我们的技术。
将使用应用程序的国家/地区的会计规则可能需要发票上的序列号。
您的用户可能习惯于根据序号进行思考。也许员工会赌谁可以打包 10000 号订单?如果有人告诉他们赌注取消了,他们可能会非常沮丧,因为新的计算机系统。
如果有问题的字段是您的主键,则即使您从 1 跳到 3 等,序列号也可以更快地插入。
但是序列号确实会带来一个安全问题:人们“猜测” URL、意外转置数字或泄露业务数据(您拥有多少用户等)。
一种选择是使用 GUID(唯一标识符类型)。它不适合大声说话或打字,但它足够随机和独特。
如果您使用的是 SQL Server 2005,新的 SequentialID() 函数将返回一个连续的 GUID,它为您提供所需的唯一性,并快速插入到您的表中。
如果您选择使用某种随机数,我鼓励您在表中还有一个默认为 GETDATE() 的 smalldatetime 列,以便您可以按创建日期对行进行排序和过滤。
您应该询问您的业务联系人,数字是否真的真的需要连续,而不是我们。
并告诉同一个业务人员,在大多数情况下,计算机系统几乎不可能对此提供无懈可击的保证。