most of the time you don't need to store NULL values in MySQL. 0 or the empty string works fine. for example, with an email column, if someone doesn't enter an email address, just store the empty string. i can't see any need for NULL.
one column i do have NULL is an age column. if an age isn't entered, i store NULL, rather than 0. that way, in case i want to do something like SELECT AVG(age) FROM ..., only the people who have an age will be averaged because the grouping functions (except COUNT(*)) ignore NULL rows. if i had instead stored 0's, those rows would lower the average.
don't use NOT NULL *IF* you need to tell the difference between an empty value (0 or empty string) and no value (NULL).
Originally posted by voostind
MySQL column types
It is not true that using the smallest column type possible leads to query results. The
reason is that, internally, MySQL uses 32-bit integers for indexes. (At least, last time I
checked it did.) So when you build an index on an integer-type like SMALLINT or TINYINT,
it will still become a 32-bit integer in the accompanying index (possibly even resulting
in worse performance when running queries!). There even was a time MySQL messed up indexes
on integer columns that weren't 32-bit, but this probably isn't true anymore. (I don't use
MySQL myself.) Of course it makes good sense to use smaller integer types that aren't
indexed and have a limited range, like someone's age.
<snip>
Declaring columns NULL or NOT NULL has nothing to do with optimization! It has to
do with the design of the database. If some table can have empty fields (as specified in
the design), it should be NULL, and not 0 or the empty string. This way, when some field
holds the value 0 (or the empty string), you'll know it's not an empty field. It's a field
that has an empty value, which is something quite different.
i got my information from the MySQL manual.

from
Get your data as small as possible:
One of the most basic optimisation is to get your data (and indexes) to take as little space on the disk (and in memory) as possible. This can give huge improvements because disk reads are faster and normally less main memory will be used. Indexing also takes less resources if done on smaller columns.
Use the most efficient (smallest) types possible. MySQL has many specialised types that save disk space and memory.
Use the smaller integer types if possible to get smaller tables. For example, MEDIUMINT is often better than INT.
Declare columns to be NOT NULL if possible. It makes everything faster and you save one bit per column. Note that if you really need NULL in your application you should definitely use it. Just avoid having it on all columns by default.
only the index pointers (is that what they're called?) are 32-bit. i just checked and changing a SMALLINT column to INT on an 880 row table increased the size of the index file. so obviously SMALLINT takes up less space in the index.
it's even more important to use smaller types, when possible, on indexed columns. they can be compared faster when doing joins and other searches. and by being smaller, they not only save disk space, but require less disk reads/writes and allow more of the index to be kept in the key_buffer (if it's a large table and assuming the table stays in the table_cache, otherwise its index blocks are released from the key_buffer). the more things you can keep in memory, the less disk access you have. but you know that.
declaring columns NOT NULL does have something to to with optimization.

i'm not sure what the manual means by "you save one bit per column." i just checked on the 880 row table. removing NOT NULL (from
one column) made the data file 840 bytes larger. so that looks more like 1
byte per
row. of course the savings are multiplied for each column you make NOT NULL.
when columns are NOT NULL, that's one less value to check for. some examples of where NOT NULL helps:
Code:
mysql> EXPLAIN SELECT * FROM table WHERE not_null_col IS NULL;
+-----------------------------------------------------+
| Comment |
+-----------------------------------------------------+
| Impossible WHERE noticed after reading const tables |
+-----------------------------------------------------+
MySQL doesn't need to check the table because not_null_col can't possibly contain a NULL row.
also, MySQL can do optimizations on things like ... LEFT JOIN t2 ON t1.col=t2.col WHERE t2.col IS NULL. in the manual, for
EXPLAIN, it says this for a value in the Extra column:
Extra
...
Not exists
MySQL was able to do a LEFT JOIN optimisation on the query and will not examine more rows in this table for the previous row combination after it finds one row that matches the LEFT JOIN criteria. Here is an example for this:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
Assume that t2.id is defined with NOT NULL. In this case MySQL will scan t1 and look up the rows in t2 through t1.id. If MySQL finds a matching row in t2, it knows that t2.id can never be NULL, and will not scan through the rest of the rows in t2 that has the same id. In other words, for each row in t1, MySQL only needs to do a single lookup in t2, independent of how many matching rows there are in t2.
Another reason for not using anything other than the default INT32 (INT == INT32) is that
other software might not understand it. If, for example, you use an ODBC connection to a
MySQL database, you should only use simple data types. Microsoft Access in particular,
which is used a lot for these kind of things, will freak out otherwise.
i'm aware of that.

i don't know if it's an issue for most people, though. if it is, they'll probably know.
Of course you shouldn't define a single field as KEY, UNIQUE and PRIMARY KEY at the same
time. But frankly I'm surprised that MySQL doesn't optimize this away. As soon as some
field is already a PRIMARY KEY, it needn't create two additional indexes. Are you sure
MySQL doesn't notice this? (If so, it's even more stupid than I thought...)
it seems to be pretty stupid.

when you do a SHOW INDEX FROM table, it shows 3 indexes.

i too thought it might ignore the KEY and UNIQUE.
Bookmarks