I am trying to design an ecommerce web application in MySQL and I am having problems choosing the correct primary keys for the user table. the example given is just a sample example for illustration.
user table have following definition
CREATE TABLE IF NOT EXISTS `mydb`.`user` (
`id` INT NOT NULL ,
`username` VARCHAR(25) NOT NULL ,
`email` VARCHAR(25) NOT NULL ,
`external_customer_id` INT NOT NULL ,
`subscription_end_date` DATETIME NULL ,
`column_1` VARCHAR(45) NULL ,
`column_2` VARCHAR(45) NULL ,
`colum_3` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `username_UNIQUE` (`username` ASC) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
UNIQUE INDEX `customer_id_UNIQUE` (`external_customer_id` ASC) )
ENGINE = InnoDB
I am facing following issues with the primary key candidate columns:
Id column
Pros
- No business meaning (stable primary key)
- faster table joins
- compacter index
cons
- not a "natural" key
- All attribute table(s) must be joined with the "master" user table, thus non-joining direct queries are not possible
- causes less "natural" SQL queries
- Leaks information: a user can figure out the number of registered user if start value is 0 (changing the start value sort this out) ii) A user register a profile as user_A at time_X and some time later as user_B at time_Y will be easily able to calculate the number of registered users over the time period ((Id for user_B) - (Id for user_A)/(time_Y - time_X))
email column
Pros
- None
Cons
- a user should be able to change the email address. Not suitable for primary key
username column
Pros
- a "natural" primary key
- Less table joins
- simpler and more "natural" queries
Cons
- varchar column is slower when joining tables
- an index on a varchar column is less compact than int column index
- very difficult to change username since foreign keys are dependent on the value. Solution: "Syncing" all foreign keys on application or not allowing a user to change the username, .e.g. a user should delete the profile a register new
external_customer column
pros
can be used as an external reference for a customer and holds no information (maybe non-editable username can be used instead? )
cons
might leaks information if it is auto incremental (if possible)
- problematic to generate unqiue value if an auto incremental surrogate id is already in use since MySQL innodb engine does not multiple auto_increment columns in same table
what are the common practice when choosing user table primary keys for a scalable ecommerce web application? all feedback appreciated