I am implementing a very simple user database for a website I am creating, and naturally I want to make sure I am working as close to “best practices” as possible. The database is in MySQL and I am struggling with the table definition.
CREATE TABLE IF NOT EXISTS 'users' (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'auto incrementing user_id of each user, unique index',
`user_email` varchar(254) COLLATE utf8_unicode_ci COMMENT 'user''s email',
`user_password_hash` text COLLATE utf8_unicode_ci NOT NULL COMMENT 'user''s password in salted and hashed format',
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_email` (`user_email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='user data' AUTO_INCREMENT=1 ;
I borrowed this table definition from php-login.net, and edited it to make user_email the unique key (the original had it as a text field, non unique).
After doing some reading, I have seen a few comments that say having a unique key/index that is this large(254*3 bytes) implies a bad database design and the fact the MySQL has a max key length of 1000 bytes makes me think I am doing something wrong. Can this database be improved or is it fine the way it is?
I do not know the inner workings of indexing in MySQL and the amount of overhead involved so I assume it is more than possible that a key this large is just not efficient.
Thanks for the help.
Making the email a unique index is fine to act as a constraint and improve lookups by email, but why not decrease the size of the email field? How many 254 character email addresses do you plan to have and can you sacrifice them by making the column a varchar(128)? I wouldn’t use it for your primary key, keep your auto incrementing bigint.
As far as other best practices, why append
user_to every column in the user table? Is there any column in the user table that does not apply to a user record? Just useid,emailetc… When writing queriesuser.idanduser.emailis cleaner thanuser.user_idanduser.user_email. Also, when you use the as foreign keys in other tables, you just refer to them asuser_id, from that I can tell the foreign key is theidcolumn of theusertable. Do this consistently throughout your database.