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

我正在建立一个非常小的 MySQL 数据库,存储,名字,姓,电子邮件和电话号码,并努力寻找每个字段的“完美”数据类型。我知道没有完美的答案,但对于这些常用的字段,一定有某种共同的约定。例如,我已经确定,一个未格式化的美国电话号码太大,不能存储为无符号整型数,它必须至少是一个二进制数。

因为我确信其他人可能会发现这很有用,所以我不想把我的问题限制在上面提到的领域。

What datatypes are appropriate for common database fields? Fields like phone number, email and address?

125842 次浏览

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

  1. 你不需要对它做任何算术运算
  2. 迟早有人会尝试(做类似的事情)在他们的区号周围加上括号。

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

  • INT (11)用于任何既是 ID 又引用另一个 ID 的内容
  • 时间戳的日期时间
  • VARCHAR (255)用于保证低于255个字符的任何内容(页面标题、名称等)
  • 几乎所有的东西都可以发短信。

Of course there are exceptions, but I find that covers most eventualities.

根据我的经验,名/姓字段应该至少有48个字符——有些来自马来西亚或印度等国家的名字的完整形式非常长。

电话号码和邮政编码,你应该 一直都是视为文本,而不是数字。通常给出的理由是有些邮政编码以0开头,在一些国家,电话号码也可以以0开头。但是真正的原因是它们不是 numbers——它们是由数字组成的 识别资料(这忽略了像加拿大这样的国家的邮政编码中有字母)。因此,将它们存储在一个文本字段中。

在 MySQL 中,您可以使用 VARCHAR 字段来获取这种类型的信息。虽然这听起来很懒,但它意味着你不必太在意正确的最小尺寸。

因为要处理的数据长度是可变的(姓名、电子邮件地址) ,所以需要使用 VARCHAR。VARCHAR 字段占用的空间量是 [field length] + 1字节,最大长度为255,因此我不会太担心找到一个完美的大小。看一下您想象的最长长度,然后将其加倍,并将其设置为您的 VARCHAR 限制。上面说..:

I generally set email fields to be VARCHAR(100) - i haven't come up with a problem from that yet. Names I set to VARCHAR(50).

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

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

下面是我使用的一些常见数据类型(虽然我不是很专业) :

| 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

我也在做同样的事情,这就是我所做的。

我使用单独的表来表示姓名、地址、电子邮件和数字,每个表都有一个 NameID 列,该列是除 Name 表之外的所有表的外键,其中 Name 表是主集群键。我使用 MainName 和 FirstName 而不是 LastName 和 FirstName 来允许业务条目和个人条目,但您可能不需要这样做。

在所有表中,NameID 列都是一个 smallint,因为我相当肯定不会创建超过32000个条目。几乎所有其他的东西都是 varchar (n) ,范围从20到200不等,这取决于您想要存储什么(生日、评论、电子邮件、非常长的名称)。这完全取决于你储存的是什么东西。

数字表是我偏离它的地方。我将它设置为有五列,分别标记为 NameID、 Phone # 、 CountryCode、 Extension 和 PhoneType。我已经讨论过 NameID 了。Phone # 是 varchar (12) ,带有检查约束,如下所示: CHECK (Phone # like’[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]’)。这样可以确保只有我想要的数据才能进入数据库,而且数据保持非常一致。分机号和国家代码我称之为可空的 smallint 但如果你愿意,可以用 varchar。PhoneType 是 varchar (20) ,不能为空。

希望这个能帮上忙!

任何身份证明

用途: INT(11)

MySQL 索引 将能够最快地解析整数列表。

任何东西,安全

使用方法: BINARY(x)BLOB(x)

您可以直接在 BINARY (x)或 BLOB (x)中以十六进制的形式存储安全令牌等。要从 binary类型检索,请使用 SELECT HEX(field)...SELECT ... WHERE field = UNHEX("ABCD....")

任何东西,日期

使用: DATETIMEDATE,或 TIME

如果需要同时存储日期和时间(而不是一对字段) ,始终使用 DATETIME,因为 DATETIME索引更适合在 MySQL 中进行日期比较。

Anything True-False

使用: BIT(1)(仅适用于 MySQL8) ,否则,使用 BOOLEAN(1)

BOOLEAN实际上只是 TINYINT(1)的一个别名,它实际上存储0到255(不完全是 true/false,是吗?)。

Anything You Want to call `SUM()`, `MAX()`, or similar functions on

用途: INT(11)

VARCHAR 或其他类型的字段不能与 SUM()等函数一起工作。

任何超过1000字符的东西

用途: 短信。

最高限额是65535。

超过65,535个字符

用途: 中文。

最高限额是16777215。

超过16,777,215字符的

Use: LONGTEXT.

最高限额是4294967295。

FirstName, LastName

用途: VARCHAR(255)

UTF-8字符每个可见字符可以占用三个字符,有些区域性不区分名和姓。此外,区域性可能在哪个名称是 第一和哪个名称是 最后方面存在分歧。您应该将这些字段命名为 Person.GivenNamePerson.FamilyName

电邮地址

用途: VARCHAR(256)

The definition of an e-mail path is set in RFC821 in 1982. The maximum limit of an e-mail was set by RFC2821 in 2001, and these limits were kept unchanged by RFC5321 in 2008. (See the section: 4.5.3.1. Size Limits and Minimums.) RFC3696, published 2004, mistakenly cites the email address limit as 320 characters, but this was an "info-only" RFC that explicitly "defines no standards" according to its intro, so disregard it.

电话

用途: VARCHAR(255)

你永远不知道电话号码什么时候会变成“1800...”,或者“1-800”,或者“1-(800)”,或者以“分机42”结尾,或者“找 Susan”。

邮政编码

用途: VARCHAR(10)

您将获得像 1234512345-6789这样的数据。

网址

用途: VARCHAR(2000)

官方标准支持的 URL 比这个长得多,但是现在很少有浏览器支持超过2000个字符的 URL

Price

用途: DECIMAL(11,2)

上升到11。