优化的数据类型+简单的数据库设计

时间:2010-07-20 17:36:06

标签: mysql database database-design innodb

我使用简单的数据库设计,我认为最好的数据库示例是电子商务,因为它确实存在很多问题,而且它对cms很熟悉。

USERS TABLE
UID              |int               | PK NN UN AI 
username         |varchar(45)       | UQ INDEX 
password         |varchar(100)      | 100 varchar for $6$rounds=5000$ crypt php sha512
name             |varchar(100)      | 45 for first name 45 for last 10 for spaces
gender           |bit               | UN ,0 for women 1 for men, lol.
phone            |varchar(30)       | see [2] 
email            |varchar(255)      | see RFC 5322 [1]
verified         |tinyint           | UN INDEX 
timezone         |tinyint           | -128 to 127 just engough for +7 -7 or -11 +11 UTC
timeregister     |int               | 31052010112030 for 31-05-2010 11:20:30 
timeactive       |int               | 01062010110020 for 1-06-2010 11:00:20

COMPANY TABLE
CID              |int               | PK NN UN AI
name             |varchar(45)       |
address          |varchar(100)      | not quite sure about 100.
email            |varchar(255)      | see users.email, this is for the offcial email
phone            |varchar(30)       | see users.phone
link             |varchar(255)      | for www.website.com/companylink 255 is good.
imagelogo        |varchar(255)      | for the retrieving image logo & storing 
imagelogosmall   |varchar(255)      | not quite good nameing huh? let see the comments
yahoo            |varchar(100)      | dont know
linkin           |varchar(100)      | dont know
twitter          |varchar(100)      | twitter have 100 max username? is that true?
description      |TEXT              | or varchar[30000] for company descriptions
shoutout         |varchar(140)      | status that companies can have.
verified         |tinyint           | UN INDEX 

PRODUCT TABLE
PID              |int               | PK NN UN AI
CID              |int               | from who?santa? FK: company.cid cascade delete
name             |varchar(100)      | longest productname maybe hahaha.
description      |TEXT              | still confused useing varchar[30000]
imagelarge       |varchar(255)      | for the retrieving product image & storing 
imagesmall       |varchar(255)      | for the retrieving small product image & storing 
tag              |varchar(45)       | for tagging like stackoverflow ( index )
price            |decimal(11,2)     | thats in Zimbabwe dollar.
  1. 请参阅Using a regular expression to validate an email address
  2. 请参阅What's the longest possible worldwide phone number I should consider in SQL varchar(length) for phone
  3. 为什么innodb具体? 请参阅引用How to choose optimized datatypes for columns [innodb specific]?

    它得到了主题所以我必须创建另一个问题,人们会明白我试图说什么,或者我可能无法解释我想要的东西。这次是它的+数据库设计。

    所以请再次复制上面的示例并将您的更改+注释与示例一样。提出建议。

    请记住INNODB mysql。阅读上面链接的引用。感谢。

4 个答案:

答案 0 :(得分:2)

我将回答这个问题,好像你在询问有关列定义的建议一样。我不会复制和粘贴你的表格,因为那是完全愚蠢的。

  • 不要将日期和时间存储为整数。改为使用DATETIME列。
  • 请记住,MySQL将DATETIME存储为GMT,但会将其显示在配置使用的任何时区。 GMT可能值setting the connection time zone,因此您的单独时区存储将起作用。
  • 请注意,并非所有时区都与格林尼治标准时间完全相同。夏令时也可以在基于小时的计算中使用猴子扳手。您可能希望存储时区字符串(即“America / Los_Angeles”)并在运行时找出正确的偏移量。
  • 您不需要为整数列指定字符数。
  • 不要害怕TEXT列。对于可以轻松超过255个字符的数据(如URL),您有很多VARCHAR(255)。

请记住,优化特定数据库引擎或优化磁盘存储是您应该做的最后一件事。使列定义适合数据。过早优化是这世界上所有邪恶的根源之一。不要担心tinyint vs smallint vs int vs bigint,或者char vs varchar vs text vs bigtext。只要数据适合,95%的时间对你来说无关紧要。

答案 1 :(得分:1)

USERS TABLE
UID              |int(11)           | PK as primery key ? NN as not null ? UN AI 
username         |varchar(45)       | UQ 
password         |varchar(200)      | 200 is better.
name             |varchar(100)      | ok
gender           |blob              | f and M
phone            |varchar(30)       | 
email            |varchar(300)      | thats 256 , put 300 insted
verified         |tinyint(1)        | UN
timezone(delate) |datetime          | this should be a php job
timeregister     |datetime          | 
timeactive       |datetime          | 

COMPANY TABLE
CID              |int(11)           | PK NN UN AI
name             |varchar(45)       |
address          |varchar(100)      | 100 is fine
email            |varchar(255)      |
phone            |varchar(30)       | 
link             |varchar(255)      |
imagelogo        |varchar(255)      | 
imagelogosmall   |varchar(255)      | the nameing is just fine for me 
yahoo            |varchar(100)      | see 3.
linkin           |varchar(100)      | linkin use real names, maybe 100 is great
twitter          |varchar(20)       | its 20 ( maybe 15 )
description      |TEXT              | 
shoutout         |varchar(140)      | seems ok.
verified         |tinyint(1)        | UN

PRODUCT TABLE
PID              |int(11)           | PK NN UN AI
CID              |int(11)           | FK: company.cid cascade delete & update
name             |varchar(100)      | 
description      |TEXT              | 
imagelarge       |varchar(255)      | 
imagesmall       |varchar(255)      | 
tag              |varchar(45)       | 
price            |decimal(11,2)     | 

在php中查看php.net/manual/en/function.date-default-timezone-set.php

$time = date_default_timezone_set('Region/Town');
$time = date( 'Y-m-d H:i:s' );
echo $time;
  1. http://www.eph.co.uk/resources/email-address-length-faq/

答案 2 :(得分:1)

您应该将所有日期/时间存储在GMT中。最佳做法是将它们转换为0偏移,然后将它们转换回用户当前所在的任何本地时区偏移。

Internet Explorer中URL的最大长度(最小公分母)为2,000个字符(只需使用TEXT)。

您没有在INT类型上设置长度(取消它们!)。 INT为32位(-2147483648至2147483647),BIGINT为64位,TINYINT为8位。

对于bool / flags,你可以使用BIT,即1或0(例如你的“已验证”)

VARCHAR(255)对于“imagelarge”和“imagesmall”来说可能太小,如果要包含图像文件名和路径(请参阅上面的最大URL长度)。

如果您对VARCHAR太大以及何时开始使用TEXT感到困惑,请使用TEXT

答案 3 :(得分:1)

对于它的价值,整数参数(例如INT(11))对于存储或优化没有任何意义。参数不表示值的最大长度或最大值范围,它只是显示的提示。这会让很多MySQL用户感到困惑,可能是因为他们已经习惯CHAR(11)表示最大长度。整数不是这样。 TINYINT(1)TINYINT(11)以及TINYINT(255)以8位整数的形式存储,并且它们具有相同的值范围。

电子邮件地址的最大长度为320个字符。本地部分为64,@为1,域为255。

我不喜欢使用VARCHAR(255)作为默认字符串声明。为什么255的长度合适? 254只是不够长而256似乎太多了?答案是人们相信每个字符串的长度存储在某个地方,并且通过将长度限制为255,他们可以确保长度只需要1个字节。他们通过允许尽可能长的字符串来“优化”,同时仍将长度保持为1个字节。

实际上,字段的长度存储在InnoDB中。存储行中每个字段的偏移量(请参阅MySQL Internals InnoDB)。如果总行长度为255或更小,则偏移量使用1个字节。如果总行长度可能超过255,则偏移量使用2个字节。由于您的行中有多个长字段,因此几乎可以肯定将偏移量存储为两个字节。无处不在的值255可以针对其他一些RDBMS实现进行优化,但不能针对InnoDB进行优化。

此外,MySQL在某些情况下将行转换为固定长度格式,根据需要填充可变长度字段。例如,当将行复制到排序缓冲区,或存储在MEMORY表中,或为结果集准备缓冲区时,它必须根据列的最大长度而不是每个可用数据的长度来分配内存。 - 基础。因此,如果您声明VARCHAR列的时间比实际使用的时间长,那么在这些情况下就会浪费内存。

这指出了尝试针对特定存储格式进行过度优化的危险。