常见的MySQL字段及其适当的数据类型


111

我正在建立一个很小的MySQL数据库,该数据库存储名字,姓氏,电子邮件和电话号码,并且正在努力寻找每个字段的“完美”数据类型。我知道没有完美的答案,但是对于诸如此类的常用字段必须有某种通用约定。例如,我确定未格式化的美国电话号码太大,无法存储为未签名的int,它必须至少是bigint。

因为我确信其他人可能会觉得这很有用,所以我不想将我的问题仅局限于上面提到的领域。

哪些数据类型适用于常见的数据库字段?电话号码,电子邮件和地址等字段?

Answers:


71

有人会发布一个比这更好的答案,但只是想指出一点,我个人不会将电话号码存储在任何类型的整数字段中,主要是因为:

  1. 您无需对其进行任何算术运算,并且
  2. 某人迟早会尝试(用类似的方式)在其区号周围放置方括号。

总的来说,我似乎几乎只使用:

  • INT(11),用于表示一个ID或引用另一个ID的任何内容
  • 时间戳记的DATETIME
  • VARCHAR(255)用于保证所有小于255个字符的字符(页面标题,名称等)
  • TEXT几乎包含所有其他内容。

当然也有例外,但我发现这涵盖了大多数可能发生的情况。


2
另外,整数最多只能支持20亿的值。那是2,000,000,000。当您要存储带有国家/地区代码的国际电话号码时,实际上没有足够的空间。我甚至不看你怎么能找到足够的空间存储喜欢655-405-4055号码(6554054055)
基比

29
另外,这是错误的。当我刚开始使用数据库时,一个比我聪明的人告诉我,仅仅是因为看起来像数字的数字并不意味着它应该或应该被视为……
da5id

14
盲目使用varchar(255)是一个坏主意。至少需要一些基本的努力来猜测长度。
Morgan Tocker

4
@Morgan Tocker:这是最佳做法,低于255个字符的任何内容都会占用相同的空间。
raveren's

7
@Raveren:这是特定于存储引擎的-存储不是唯一的成本。排序数据和临时表(内存引擎)将使用固定数量。
Morgan Tocker 2010年

44

这是我使用的一些常见数据类型(尽管我不是专业人士):

| Column           | Data type     | Note
| ---------------- | ------------- | -------------------------------------
| id               | INTEGER       | AUTO_INCREMENT, UNSIGNED                                                          |  
| uuid             | CHAR(36)      | or CHAR(16) binary                                                                |  
| title            | VARCHAR(255)  |                                                                                   |  
| full name        | VARCHAR(70)   |                                                                                   |  
| gender           | TINYINT       | UNSIGNED                                                                          |  
| description      | TINYTEXT      | often may not be enough, use TEXT 
                                     instead          
| post body        | TEXT          |                                                                                   |  
| email            | VARCHAR(255)  |                                                                                   |  
| url              | VARCHAR(2083) | MySQL version < 5.0.3 - use TEXT                                                  |  
| salt             | CHAR(x)       | randomly generated string, usually of 
                                     fixed length (x)    
| digest (md5)     | CHAR(32)      |                                                                                   |  
| phone number     | VARCHAR(20)   |                                                                                   |  
| US zip code      | CHAR(5)       | Use CHAR(10) if you store extended 
                                     codes      
| US/Canada p.code | CHAR(6)       |                                                                                   |  
| file path        | VARCHAR(255)  |                                                                                   |  
| 5-star rating    | DECIMAL(3,2)  | UNSIGNED                                                                          |  
| price            | DECIMAL(10,2) | UNSIGNED                                                                          |  
| date (creation)  | DATE/DATETIME | usually displayed as initial date of 
                                     a post                                       |  
| date (tracking)  | TIMESTAMP     | can be used for tracking changes in a 
                                     post                                        |  
| tags, categories | TINYTEXT      | comma separated values *                                                          |  
| status           | TINYINT(1)    | 1  published, 0  unpublished,  You 
                                     can also use ENUM for human-readable 
                                     values
| json data        | JSON          | or LONGTEXT       

4
@yentsun-电子邮件实际上只有254;阅读了尼尔·麦圭根(Neil McGuigan)发布的问题
RustyTheBoyRobot 2012年

16

以我的经验,名字/姓氏字段至少应包含48个字符-有些国家(例如马来西亚或印度)的名字格式很长。

您应该始终将电话号码和邮政编码视为文本,而不是数字。给出的正常原因是,邮政编码以0开头,在某些国家/地区,电话号码也可以以0开头。但真正的原因是,它们不是数字 -它们是恰好组成的标识符数字位数(并且忽略了像加拿大这样的邮政编码中带有字母的国家/地区)。因此,将它们存储在文本字段中。

在MySQL中,您可以将VARCHAR字段用于此类信息。虽然听起来很懒,但这意味着您不必太在乎正确的最小大小。


为了进一步支持您对邮政编码的评论,在英国或加拿大等国家/地区,邮政编码为字母数字。
安迪·贝尔德(

您可能需要予以关注的权利最小尺寸stackoverflow.com/questions/262238/...
罗希特邦加

@iamrohitbanga虽然您对正确定义的数据是正确的,但对于名称VARCHAR(255)来说却是正确的。
staticsan

9

由于您将要处理长度可变的数据(名称,电子邮件地址),因此您需要使用VARCHAR。VARCHAR字段占用的空间量为[field length]+ 1个字节,最大长度为255,因此,我不必担心要找到一个理想的大小。看看您想像的最长的长度,然后将其加倍并将其设置为VARCHAR限制。那说...:

我通常将电子邮件字段设置为VARCHAR(100)-我还没有想到这个问题。我设置为VARCHAR(50)的名称。

正如其他人所说,电话号码和邮政编码实际上不是数字值,它们是包含数字0-9(有时甚至更多!)的字符串,因此您应该将它们视为字符串。VARCHAR(20)应该足够了。

请注意,如果您将电话号码存储为整数,许多系统将假定以0开头的数字是八进制(以8为底)的数字!因此,完美有效的电话号码“ 0731602412”将作为十进制数字“ 124192010”输入数据库中!


1

我正在做同一件事,这就是我所做的。

我为名称,地址,电子邮件和数字使用了单独的表,每个表都有一个NameID列,该列是除Name表以外的所有内容的外键,在该表上它是主群集键。我使用MainName和FirstName代替LastName和FirstName来进行业务输入和个人输入,但是您可能不需要这样做。

NameID列在所有表中都将成为smallint,因为我敢肯定我输入的条目不会超过32000。几乎所有其他内容都是varchar(n),范围从20到200,这取决于您要存储的内容(生日,评论,电子邮件,很长的名字)。这实际上取决于您要存储什么类型的东西。

我从中偏离了Numbers表。我将其设置为五列,分别标记为NameID,Phone#,CountryCode,Extension和PhoneType。我已经讨论过NameID。电话号码为varchar(12),检查约束如下所示:CHECK(电话号码类似'[0-9] [0-9] [0-9]-[0-9] [0-9] [0 -9]-[0-9] [0-9] [0-9] [0-9]')。这样可以确保只有我想要的内容才能进入数据库,并且数据保持非常一致。我将扩展名和国家/地区代码称为可为null的smallint,但是如果您愿意的话,可以使用varchar。PhoneType为varchar(20),并且不能为空。

希望这可以帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.