【问题标题】:Optimized datatypes + simple database design优化的数据类型+简单的数据库设计
【发布时间】:2010-07-20 17:36:05
【问题描述】:

我正在使用一个简单的数据库设计,我认为最好的数据库示例是电子商务,因为它确实有很多问题,而且它对 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

为什么是 innodb 特定的? 请看报价How to choose optimized datatypes for columns [innodb specific]?

它的话题,所以我必须创建另一个问题,人们不明白我想说什么,或者我无法解释我想要什么。这次是它的 + 数据库设计。

所以请再次复制上面的示例并将您的更改+ cmets 就像示例一样。给个建议吧。

记住 INNODB mysql。阅读上面链接上的报价。谢谢。

【问题讨论】:

  • 您到底要什么?你可以说得更详细点吗?您要解决的确切问题是什么?此外,标题中不需要括号中的内容,例如“[innodb]”,这就是标签的用途。
  • 我的数据库设计够了吗?我只是想知道人们如何使用这个数据库方案。关于innodb的事情,谢谢,它看起来确实有点矫枉过正,在innodb中有些像CHAR比varchar更快,我不擅长这些事情所以我在这里问。

标签: mysql database database-design innodb


【解决方案1】:

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

  • 不要将日期和时间存储为整数。请改用 DATETIME 列。
  • 请记住,MySQL 将 DATETIME 存储为 GMT,但在配置为使用的任何时区中显示它们。格林威治标准时间可能值得setting the connection time zone,以便您的单独时区存储可以正常工作。
  • 请记住,并非所有时区都是与 GMT 的整小时偏移。夏令时也可以在基于小时的计算中使用活动扳手。您可能想要存储时区字符串(即“America/Los_Angeles”)并在运行时计算出正确的偏移量。
  • 您无需为整数列指定字符数。
  • 不要害怕 TEXT 列。对于很容易超过 255 个字符的数据(例如 URL),您有很多 VARCHAR(255)。

请记住,针对特定数据库引擎进行优化或针对磁盘存储进行优化是您最不应该做的事情。使您的列定义适合数据。过早的优化是这个世界上万恶之源之一。不要担心 tinyint vs smallint vs int vs bigint,或者 char vs varchar vs text vs bigtext。只要数据合适,在 95% 的情况下对您来说都无关紧要。

【讨论】:

  • 过早优化。我喜欢那个。顺便说一句,我使用 php 使用 time(),使用 php 做第二个工作更好吗?还是让mysql来做?
  • 如果你使用 PHP,你应该使用DateTime。它还包括comprehensive time zone support
【解决方案2】:

您应该将所有日期/时间存储在 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

【讨论】:

  • 哦,好吧,我只是按照示例进行操作。无论如何,谢谢JhonB。顺便说一句,BIT 是个好主意!再次感谢。
【解决方案3】:
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/

【讨论】:

  • 谢谢,我也检查了我的 Twitter 帐户以了解我的用户名长度。
【解决方案4】:

对于它的价值,整数参数(例如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 列比您实际使用的时间长得多,那么在这种情况下您就是在浪费内存。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多