views:

477

answers:

3

Funny thing I've found abount mysql. MySQL has a 3 byte numeric type - MEDIUMINT. Its range is from -8388608 to 8388607. It seems strange to me. Size of numeric types choosen for better performance, I thought data should be aligned to a machine word or double word. And if we need some restriction rules for numeric ranges, it must be external relative to datatype. For example:

CREATE TABLE ... (
  id INT RANGE(0, 500) PRIMARY KEY
)

So, does anyone know why 3 bytes? Is there any reason?

+1  A: 

The alignment issue you mentioned applies mostly to data in RAM. Nothing forces MySQL to use 3 bytes to store that type as it processes it.

This might have a small advantage in using disk cache more efficiently though.

Mehrdad Afshari
Yes, but modern processor doesn't have instructions for operating with 3-bytes data. When taking a sum of 3 byte numbers processor will sum two 4 byte numbers with zerofilled high order byte. Is this correct?The only advantage I see on 3 byte numbers is space. On large dataset 3-bte numbers will be 25% smaller.
dotsid
Yes, that's true. I wouldn't normally use that data type though ;)
Mehrdad Afshari
+5  A: 

The reason is so that if you have a number that falls within a 3 byte range, you don't waste space by storing it using 4 bytes.

When you have twenty billion rows, it matters.

chaos
Space is very important in database operations.
hobodave
This doesn't answer the alignment question, which was the point of the original question.
Svante
Mehrdad answered that: the alignment doesn't matter for the purposes I'm talking about.
chaos
+1  A: 

We frequently use tinyint, smallint, and mediumint as very significant space savings. Keep in mind, it makes your indexes that much smaller.

This effect is magnified when you have really small join tables, like:

id1 smallint unsigned not null,
id2 mediumint unsigned not null,
primary key (id1, id2)

And then you have hundreds of millions or billions of records.

gahooa
Processors can't compare 3-bytes numbers. So in memory index should contain 4 bytes on each index position. Are you shure that index size is 3 byte long if you using mediumint?
dotsid