Say I have a table that uses a string as its Primary Key. For example, a sessions table ( I will keep this to 4 characters so I can make my examples clearer).
I will also add an Auto Increment column to keep my example closer to reality (in case it makes a difference).
CREATE TABLE sessions (
`id` INT AUTO INCREMENT,
`key` CHAR(4) NOT NULL,
PRIMARY KEY(`key`),
UNIQUE KEY `idx_key` ( `key` )
);
I can insert data into the table.
INSERT INTO sessions (`key`) VALUES ('abcd');
Because this is a session ID it comes from a browser, so I don't trust it and use proper bind values in the code that handles the requests. A malicious user can send various strings here but they will always end up as strings and not injection attacks. That's fine. MySQL will happily truncate this data and issue a warning.
INSERT INTO sessions(`key`) VALUES ('abcdefg');
Warning (Code 1265): Data truncated for column 'key' at row 1
However, this is only "fine" (it's not fine, but whatever) for creating rows. The same operation first looks for a row before trying to insert it. You know - upsert. MySQL does not bother to truncate this data, and decides it is not in the table.
SELECT * FROM sessions WHERE `key` = 'abcdefg';
Empty set (0.00 sec)
This means that my insert from earlier was even more not fine, because when I insert the data, MySQL truncates it to a value that does exist.
INSERT INTO sessions (`key`) VALUES ('abcdefg');
Warning (Code 1265): Data truncated for column 'key' at row 1
Error (Code 1062): Duplicate entry 'abcd' for key 'idx_key'
The website code does not know the constraint on this column and I have no intention of giving it this information.
How can I get MySQL to compare only the first N characters of the string, where N is the (max) length of the text field?