The subquery should be correlated:
SELECT uid
FROM users
WHERE flname LIKE '%john%'
AND NOT EXISTS
( SELECT * --- doesn't matter what you put here for EXISTS subqueries
FROM relationship
WHERE `from` = 60
AND `to` = users.uid --- this line added
) ;
(unrelated to the issue)
Whoever told you that it's a good idea to use reserved words like to
and from
as column or table names, deserves a kick.
You can have the same results with a LEFT JOIN / IS NULL
or a NOT IN
query:
SELECT uid
FROM users
WHERE flname LIKE '%john%'
AND uid NOT IN
( SELECT `to`
FROM relationship
WHERE `from` = 60
) ;
KEY-VALUE NO!!!
A table for phone numbers -- sure. It would have userid, phone_num, and (if you like) a phone type, such as ENUM('fax', 'home', ...). Then JOIN to the main table.
To keep unlimited, unsearchable data, have a column with a bunch of key-value stuff. I like to do it in JSON, then compress it (in the app), and store it into a BLOB or MEDIUMBLOB. That makes it easily accessible by the app, reasonable compact, and quite open-ended.
In the table, have only columns that you need to search on; put the rest into the extra JSON column.
More discussion:
http://forums.mysql.com/read.php?125,428546,428769#msg-428769
http://forums.mysql.com/read.php?125,402095,402218#msg-402218
Another approach is MariaDB's "dynamic columns". This even lets you index randomly added 'columns'.
2000-3000 customers -- Yawn.
Best Answer
Yes. You should also say
UNSIGNED
:TINYINT UNSIGNED
. Range 0..255; 1 byte.Actually, it is such a tiny optimization that I don't bother mentioning it.
Think about using the smallest datatypes when you first
CREATE
the table; it is messier to make the change later.SMALLINT UNSIGNED
: 0..65535, 2 bytesMEDIUMINT UNSIGNED
: 0..16M, 3 bytesINT UNSIGNED
: 0..4B, 4 bytesKeep in mind that certain operations "burn"
AUTO_INCREMENT
ids. This could lead to an unexpected overflow. Examples:INSERT IGNORE
andREPLACE
. They may preallocate an id before realizing that it won't be needed.