开发者

Optimized datatypes + simple database design

i am using a simple database design and i think the best database example is e-commerce, because it does have a lot of problems, and its familiar to 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. see Using a regular expression to validate an email address
  2. see What's the longest possible worldwide phone number I should consider in SQL varchar(length) for phone

why innodb specific ? please see quote How to choose optimized开发者_JAVA百科 datatypes for columns [innodb specific]?

its getting of the topic so i have to create another question and it people doent understand what im trying to say, or maybe i cant explain what i want there . this time its + database design.

so again please copy the example above and put your changes + comments just like the example. give an advice about it.

Remember for INNODB mysql. read the quote on above link. thanks.


I'm going to answer this as if you're asking for advice on column definitions. I will not copy and paste your tables, because that's completely silly.

  • Don't store dates and times as integers. Use a DATETIME column instead.
  • Keep in mind that MySQL stores DATETIMEs as GMT, but presents them in whatever timezone it's been configured to use. It may be worth setting the connection time zone to GMT so that your separate time zone storage will work.
  • Keep in mind that not all time zones are full hour offsets from GMT. Daylight Saving Time can throw a monkey wrench in hour-based calculations as well. You may want to store the time zone string (i.e. "America/Los_Angeles") and figure out the proper offset at runtime.
  • You do not need to specify a character count for integer columns.
  • Don't be afraid of TEXT columns. You have a lot of VARCHAR(255)s for data that can easily be longer than 255 characters, like a URL.

Keep in mind that optimizing for a specific database engine, or optimizing for storage on disk is the very last thing you should do. Make your column definitions fit the data. Premature optimization is one of the many roots of all evil in this world. Don't worry about tinyint vs smallint vs int vs bigint, or char vs varchar vs text vs bigtext. It won't matter for you 95% of the time as long as the data fits.


You should store all your dates/times in GMT. It's a best practice to convert them to 0 offset and then convert them back to whatever local time zone offset the user is currently in for display.

The maximum length of a URL in Internet Explorer (the lowest common denominator) is 2,000 characters (just use TEXT).

You don't set lengths on INT types (take them off!). INT is 32 bits (-2147483648 to 2147483647), BIGINT is 64 bits, TINYINT is 8 bits.

For bool/flags you can use BIT which is 1 or 0 (your "verified" for example)

VARCHAR(255) might be too small for "imagelarge" and "imagesmall" if it is to includes the image file name and path (see above for max URL length).

If you are confused on how big a VARCHAR is too big and when to start using TEXT, just use TEXT!

  • 10.2. Numeric Types


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)     | 

in php see 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/


For what it's worth, the integer argument (e.g. INT(11)) is not meaningful for storage or optimization in any way. The argument does not indicate a max length or max range of values, it's only a hint for display. This confuses a lot of MySQL users, perhaps because they're used to CHAR(11) indicating max length. Not so with integers. TINYINT(1) and TINYINT(11) and TINYINT(255) are stored identically as an 8-bit integer, and they have the same range of values.

The max length of an email address is 320 characters. 64 for the local part, 1 for @, and 255 for the domain.

I am not a fan of using VARCHAR(255) as a default string declaration. Why is 255 the right length? Is 254 just not long enough and 256 seems too much? The answer is that people believe that the length of each string is stored somewhere, and by limiting the length to 255 they can ensure that the length only takes 1 byte. They've "optimized" by allowing as long a string as they can while still keeping the length to 1 byte.

In fact, the length of the field is not stored in InnoDB. The offset of each field in the row is stored (see MySQL Internals InnoDB). If your total row length is 255 or less, the offsets use 1 byte. If your total row length could be longer than 255, the offsets use 2 bytes. Since you have several long fields in your row, it's almost certain to store the offsets in two bytes anyway. The ubiquitous value 255 may be optimized for some other RDBMS implementation, but not InnoDB.

Also, MySQL converts rows to a fixed-length format in some cases, padding variable-length fields as necessary. For example, when copying rows to a sort buffer, or storing in a MEMORY table, or preparing the buffer for a result set, it has to allocate memory based on the maximum length of the columns, not the length of usable data on a per-row basis. So if you declare VARCHAR columns far longer than you ever actually use, you're wasting memory in those cases.

This points out the hazard of trying to optimize too finely for a particular storage format.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜