1

对于购物车,我想建立一个邮政编码数据库,我的承运人可以在其中发货。

我可能有几个运营商,所以我正在寻找一个灵活的解决方案。并且有 2 种付款方式 - COD(现金)和预付(网上银行)。

来自其中一家承运人的运输邮政编码列表有 2,775 个 COD 方法条目和 4,139 个预付付款条目。

设计#1(感谢这个答案

我将直接列表转换为范围(如 {1,2,3,5,8,9} => {(1,3), (5,5), (8,9)}),并具有模式 -

carrier
        id(int) | name (varchar)

cod_zipcodes
        start(int) | end(int) | carrier(fk::carrier.id)

prepaid_zipcodes
        start(int) | end(int) | carrier(fk::carrier.id)

在转换为范围时,预付费邮政编码缩小到 1,593(38%),鳕鱼邮政编码缩小到 842(30%)。

设计#2

cod_zipcodes
    zipcode(int)

prepaid_zipcodes
    zipcode(int)

基本上这个设计只是有列表。如果有多个运营商,我会合并列表。所以我丢失了哪个承运人为特定邮政编码发货的信息。但这不是问题(但如果它被整理出来,那也不是问题!)。我只想查找数据库,客户输入的邮政编码在我们的允许列表中。

我对实时数据库的经验有限。请指出哪种设计更好,或建议您自己的设计。

谢谢!

4

1 回答 1

1

第一个设计可能是最紧凑的;可以通过在start和上添加跨越索引来优化它end。您还可以像这样组合两种付款方式:

zipcodes
    start(int) | end(int) | carrier(fk::carried.id) | cod (0, 1) | prepaid (0, 1)

carrier字段是可选的,但您可以稍后在需要更新一个运营商的邮政编码范围时使用它。

不要试图变得聪明,根据是否codprepaid可用将范围合并在一起;您可以输入具有不同运营商和付款类型可用性的多个范围。要查询它们,您将使用:

SELECT COUNT(cod), COUNT(prepaid) 
FROM zipcodes 
WHERE start <= :start AND :end <= end

cod这将给出包含特定邮政编码和/或特定邮政编码的单行prepaid(即使它可能匹配多个数据库行。

当承运人更改其邮政编码范围和付款可用性时,最简单的方法是删除该承运人的所有行并重新填充(使用表锁);如果您决定保留该数据库字段,这对您来说非常容易。


您的第二个设计看起来更像是您从运营商那里接收邮政编码列表的方式,并且管理更加简化。不过,我会再次将它们放在一张桌子上:

zipcodes
    zipcode | cod (0, 1) | prepaid(0, 1)

By choosing ENUM datatype you can get pretty good data compression as well. Updating this table when a carrier changes their delivery data is less trivial, because the carrier field is missing, so that means you have to eitherwrite a script that detects the addition, deletion and updates of a particular zip code or start over completely with both carrier data.


If updates are rare and you don't mind taking the whole table down when it does happen, I would recommend the second option. By adding cod and prepaid types in each row rather than two separate tables you can use a primary key for faster lookups compared to the range solution.

If you like flexibility and the fact that you can tell which carrier is supported on a particular range I would go for the first option; the index is still fast enough for most cases and the table size is likely comparably with the second option.

于 2012-06-28T08:27:14.160 回答