普通人字段的最佳实践(姓名、电子邮件、地址、性别等...)

Sno*_*Mac 43 database-design best-practices

常见字段的长度和数据类型最常见的最佳实践是什么,例如:

  • 地址
  • 电子邮件
  • 性别
  • 状态
  • 城市
  • 国家
  • 电话号码

等等....

Jus*_*ave 50

我倾向于对任何一套通用的最佳实践持怀疑态度,因为对于这些领域中的大多数而言,细节决定成败。仅仅因为信息相对常见并不意味着您的应用程序使用数据的方式与其他应用程序使用它的方式完全相同。这意味着您的数据模型可能需要略有不同。

  • 名字和姓氏:你为什么要捕捉这个名字?如果您需要获取一个人的法定全名(即您正在准备法律文件或出生证明),您可能希望为人们提供更多的输入空间,而不是您只要求输入一个人的姓名,以便您在您的新 Web 应用程序中可以调用它们。
  • 地址:你打算用这个地址做什么?你存储什么样的地址?如果您在美国存储要创建抵押的房产的地址,您可能非常关心获得完全标准化的地址,在这种情况下,数据模型可能会非常接近您的地址标准化工具返回。如果您只是希望人们能够输入地址来交付产品,那么几行自由格式文本可能就足够了。那里的行的长度可能取决于执行诸如打印地址标签之类的下游过程的要求。
  • 状态:假设您可以识别有效的状态值,创建一个STATE表并在STATEADDRESS表之间创建外键关系可能是有意义的。但是识别有效值的能力意味着您至少将有效地址集限制在一组特定的国家/地区。这对许多网站来说都很好,但是你必须做一些工作来支持一个新的国家。
  • 城市:如果您正在处理可能存在城市级法规的数据(即根据城市应用不同类型的税率),您可能希望像对待国家一样对待它,并有一个CITY表与有效城市CITYADDRESS表之间的外键关系。另一方面,如果您只是想让产品交付,而您不太关心表格中是否有同一个城市的不同版本,那么让用户自由输入文本就足够了。当然,如果您要存储外键,您将有大量的工作来确保您拥有所有有效值。但是有些产品的重点是公司已经完成了这项工作(即销售税数据库)。
  • 电话:你用电话号码做什么?为什么?一些应用程序希望以用户决定输入的任何格式接收电话号码,并为所有后续查询保留该格式。如果您正在设计个人通讯录,其中用户对电话号码的存储和显示方式有自己的偏好,这将很常见。其他应用程序可能希望忽略输入的格式,仅提取数字字符,然后在检索时格式化数据,以便所有电话号码具有相似的格式。如果您要迎合企业,您可能需要一个单独的字段供用户输入扩展名。如果您尝试支持出站呼叫流程,您可能需要将区号和国家/地区代码存储在单独的列中,因为您
  • 性别:对于许多应用程序,将性别代码(“M”或“F”)存储在表中是完全合理的。另一方面,在某些情况下,您可能需要其他选项(其他、双性人、跨性别者),或者您需要存储诸如出生性别和当前性别之类的信息。


gbn*_*gbn 25

您也可以根据样本数据和预期受众进行猜测。这取决于您的位置。

一些注意事项:

地址:

姓名:

电话号码:国际代码、长度、手机与房屋、仅允许手机作为号码

  • 最后两个链接(“姓氏在前”和“最长的……”)已损坏。 (3认同)
  • Wayback Machine 有一篇“姓在先”的文章:https://web.archive.org/web/20160823135055/http://www.solidether.net/2008/jul/22/last-name-first/ (3认同)

mrd*_*nny 10

除了上面的好答案之外,不要忘记接受 unicode 字符。仅仅因为您在美国并不意味着您不想在您的专栏中接受外国字符。

也就是说,我通常建议名称使用 50 个字符。320 对于电子邮件地址应该绰绰有余(您可以检查 ANSI 标准以确保)。对于地址错误,请注意 255 个字符。虽然您可能永远不需要那么大的地址,但如果您包括 C/O 线路和类似的东西,您可能会需要。城市应该很大,那里有一些很长的城市名称。对于 state 使用 child table,与 country 相同。对于邮政编码,不要忘记比美国邮政编码长的国际邮政编码。仅仅因为你不支持国际,你仍然可能是。有很多美国公民住在不同的县,包括军人。

不要忘记 state 应该是可选的,因为许多国家/地区没有 state。


Nei*_*gan 9

我的屁股因为坐在篱笆上而变得酸痛,所以我只想抛出一些答案,并希望不会被否决投票而被遗忘。请提出建设性的批评意见。

电子邮件地址:

分钟:6 (a@g.cn)。如果您想跟踪本地域电子邮件地址,则为 3
最大:320 254 (RFC)

验证电子邮件的代码量实际上是疯狂的,所以让我们假设它是有效的,如果它有一个“@”

您可能希望将电子邮件地址抽象为“通信方法”,以便您可以轻松列出与用户进行通信的所有方法。

性别

性别会随着时间而变化,因此您可以跟踪它是否对您很重要。按照http://en.wikipedia.org/wiki/ISO/IEC_5218

NOT_KNOWN(0),
MALE(1),
FEMALE(2),
NOT_APPLICABLE(9);
Run Code Online (Sandbox Code Playgroud)

地址:诺拉姆

我要走便宜的路,坚持使用北美地址。

主要是因为税收,所以很方便抽象国家、部门、市和县。税收可以适用于多个级别,因此如果您可以将税率指向抽象的地理区域,那么您就是黄金。

地理区域:

id: int  
type: {country, division, county, city, indian reservation}  
name: varchar(45)  [1]
abbreviation: nullable varchar(4)  
parent_id: nullable int  
Run Code Online (Sandbox Code Playgroud)

地址:

id: int  
postal_area_id: int, references GeographicArea  
county_or_city_id: int, references GeographicArea  
street_address: varchar(255)  
suite: nullable varchar(255)  
Run Code Online (Sandbox Code Playgroud)

如果需要,添加第 2 行和第 3 行。

http://en.wikipedia.org/wiki/Address_(geography)

现在,地址就是地址。一个地址可以住多个人,一个人可以同时拥有多个地址,随着时间的推移,您需要一个多对多的表。

聚会地址

party_id: int references Party  
address_id: int references Address  
purpose: {home, work, ...}  
Run Code Online (Sandbox Code Playgroud)

如果随着时间的推移进行跟踪,则添加一个from_date和可为空的to_date

电话号码

一个聚会可以有多个电话号码,一个电话号码可以供多人使用。电话号码可用于传真、电话呼叫、调制解调器等,并可具有分机号。这些都会随着时间而改变。

电话号码

id: int  
value: varchar(15) - the max allowed by the ITU  
Run Code Online (Sandbox Code Playgroud)

最小值可能是 3(对于“911”),或者可能是 7(“310-4NET”,这是一种特殊的本地号码,不允许您拨打区号)

如有必要,您可以将其拆分为国家/地区代码等。

您应该使用http://en.wikipedia.org/wiki/E.164标准

派对电话号码

party_id: int references Party  
phone_number_id references PhoneNumber  
extension: nullable varchar(11) - ITU max  
purpose: {home, work, fax, modem, ...}  
Run Code Online (Sandbox Code Playgroud)

姓名

名字很难。原因如下:

  1. 有些人的合法姓名中只有一个词http://en.wikipedia.org/wiki/List_of_legally_mononymous_people

  2. 有些人的名字有很多字http://en.wikipedia.org/wiki/Wolfe%2B585,_Senior

  3. 有些人同时有多个名字(比如我的大学有很多亚洲学生,但他们喜欢使用“首选”更西化的名字)

  4. 有时,您需要随时间跟踪人们的姓名,例如婚前姓名和已婚姓名。

  5. 您出于各种充分的理由想要抽象个人和组织

    创建表方(id bigserial 主键);

    创建表party_name(id bigserial主键,party_id bigint not null引用party(id),type smallint not null引用party_name_type(id) --elided, ex "maiden", "legal" );

    创建表 name_component( id bigserial 主键,party_name_id bigint not null 引用 party_name(id),type smallint not null 引用 name_component_type(id),--elided ex "given" name text not null );