地址数据库有多糟糕?

时间:2012-06-21 08:39:07

标签: sql database structure normalization street-address

我仍然是数据库,规范化等的新手,我可能需要一些帮助。这里附上我的数据库结构的一部分,我认为我的方法是一个坏主意。在这里,我们的国家可以划分为不同的省份,所有城市/城镇都属于特定的省份,而barangay(最接近的Layman的术语是区域,我猜)。因此,如果所有地方,无论你在我们国家的哪个地方,你必须拥有那个特定的城镇,城市/城镇。我做的是我使用外键来指代barangay,city / town,province。这是个坏主意吗?

如果我创建tblCustomer_Address以从Country_ID: Int FK分隔Province_ID: Int FKCityTown_ID: Int FKBaranggay_ID: Int FKtblCustomer,我会有多大的不同?

谢谢!

tblCustomer(
  Customer_Id: Int PK
  Customer_FName: String
  Customer_MName: String
  Customer_LName: String
  Country_ID: Int FK
  Province_ID: Int FK
  CityTown_ID: Int FK
  Baranggay_ID: Int FK
  Additional_Address_Details: String
 )
tblCountry(
  Country_Id: Int PK
  Country_Name: String
)
tblProvince(
  Province_Id: Int PK
  Province_Name: String
)
tblCityTown(
  CityTown_Id: Int PK
  CityTown_Name: String
)
tblBarangay(
  Barangay_Id: Int PK
  Barangay_Name: String
)

* 编辑:顺便说一句,我忘了提。我的项目的一部分是报告生成,所以我想到的是跟踪位置。因此,我想为barangays,城市/城镇,省份分别设置桌子,让每个人都与众不同。

3 个答案:

答案 0 :(得分:0)

非常糟糕,因为你必须维护国家,城市和地区的可用选项。

就个人而言,我只是创建一个addresses数据库表,根据hCard微格式创建地址组件的字段:

CREATE TABLE IF NOT EXISTS `addresses` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `extended_address` varchar(128) DEFAULT NULL,
  `street_address` varchar(128) NOT NULL,
  `locality` varchar(128) NOT NULL,
  `region` varchar(128) DEFAULT NULL,
  `postal_code` varchar(128) DEFAULT NULL,
  `country_name` varchar(128) NOT NULL,
  PRIMARY KEY (`id`)
)

答案 1 :(得分:0)

在我看来,一个城市或省份将存在一个城市,一个省内将存在一个城市,一个省份将存在一个省。如果您拥有位置类型为Barangay,City,Province,Rural或country的位置表以及指向层次结构中父位置的parentID的结构如何。然后,您的客户的位置ID指向层次结构中的任何位置。新的位置可以添加为存在于城市,省(农村)区域或国家。表格如下所示:

tblLocation(
LocationID int PK,
ParentID int FK references tblLocation LocationID,
LocationType int FK references tbllocationTypes,
LocationName
)

无法将其添加为评论,因此这是一个更完整的实现:

CREATE TABLE LocationType
(
    LocationTypeID int not null primary key,
    LocationTypeName varchar(20) not null unique
)
GO
CREATE TABLE Location (
    LocationID int not null primary key,
    ParentId int null references Location (LocationID),
    LocationName varchar(100),
    LocationTypeID int not null references LocationType (LocationTypeID)    
)
GO
CREATE Table Customer (
    CustomerID int not null primary key,
    FirstName varchar(50),
    MiddleName varchar(50),
    LastName varchar(50),
    LocationID int references Location (LocationID)
)
GO
CREATE TABLE City(  
    CityID int not null primary key references Location (LocationID),
    PostCode varchar(20) not null
)
GO
CREATE VIEW DetailedLocation AS 
    SELECT L.*, C.PostCode FROM Location AS L
    LEFT OUTER JOIN City AS C
    ON C.CityID = L.LocationID

答案 2 :(得分:0)

问题在于您没有以正确的方式处理地址。如果你真的不需要完整的地址(或者我只是在这里错过了吗?)而不仅仅是在客户表中有一个Baranggay字段就是“好的”。在任何其他情况下,您应该有一个地址表,只需引用customer表中的addressID即可。除非客户当然应该能够拥有多个地址,在这种情况下,您应该为此m:n关系引入一个CustomerAddressRel表。

无论如何,整个地址分成多个字段和/或表格是没有意义的。一个特定的baranngay将永远属于一个城镇,该镇到一个省,而该省到一个国家(国家?如果这是多个国家,你需要一个不同的格式,因为baranngay不是一个国际概念!)。因此,在地址中跟踪baranggay并且有一个不同的表来保存baranngay所属的城镇和省份真的非常好。

对于长文本感到抱歉,但如果我提出修改后的方案,我觉得它根本无济于事。您需要了解某些决策的原因,然后根据您当前的数据集和预期覆盖面做出最佳决策。如果你有可能走向国际化,请确保数据方案现在已经准备就绪。

编辑:

好吧那么,我认为如果我把它放下来最好。如果你想要面向未来并且灵活,至少只要你对菲律宾和Barangay属于一个城镇有所限制:

tblCustomer(
    Customer_ID: Int PK
    Customer_FName: String
    Customer_MName: String
    Customer_LName: String
)

tblCustomerAddressRel(
    Customer_ID: Int FK
    Address_ID: Int Fk
    Type: (Mailing, Billing, Historic,...)
)

tblAddress(
    Address_ID: Int PK
    Baranggay_ID: Int FK
    Additional_Address_Details: String (<< this looks like a bad idea btw)
)

tblCountry(
    Country_ID: Int PK
    Country_Name: String
)

tblProvince(
    Province_Id: Int PK
    Province_Name: String
    County_ID: Int FK
)
tblCityTown(
    CityTown_ID: Int PK
    CityTown_Name: String
    Province_ID: Int FK
)
tblBarangay(
    Barangay_ID: Int PK
    Barangay_Name: String
    CityTown_ID: Int FK
)