How to get the right words from a MySQL database containing a dictionary from user letter input?
Not. A relational database table is not a suitable data structure to solve this problem as efficiently as you need.
Instead, you create a trie data structure from a dictionary (or, if you're really a buff, you create a dawg - oriented acyclic word graph that is a kind of compressed trie.)
Once you have trie / dawg, it becomes very inexpensive to test every word in a dictionary against a given rack, because you can "cut" entire huge branches of the dictionary that cannot be combined in a rack.
Let's look at a small example. Suppose you have the dictionary "OP, OPS, OPT, OPTS, POT, POTS, SOP, SOPS, STOP, STOPS". From this, you create this trie: (Nodes with $ are those marked as "the word may end here").
^root^ / | \ OPS | | / \ P$ OOT / \ | | | T$ S$ T$ P$ O | | | | S$ S$ S$ P$ | S$
and you have an OPS rack - what are you doing?
First you say: โCan I go down the O branch?โ Yes you can. So now the problem is the match of โPSโ with branch O. Can you go down the subbrand? Yes. Does he have a word end marker? Yes, so the OP is a coincidence. Now the problem is that "S" matches the OP branch. Can you go down the T branch? Not. Can you go down the S branch? Yes. You now have an empty rack and you must map it to the OPS branch. Does he have a word end marker? Yes! So that is OPS. Now go back to the root.
Can you go down the P branch? Yes. Now the problem is to map the OS to branch P. Go down the PO branch and map to S - this will not work. Rollback to the root.
And again, you see how this happens. In the end, we go down the SOP branch and find the end of the word in SOP, so "SOP" corresponds to this stance. We do not go down the ST branch because we do not have T.
We tried all possible words in the dictionary and found that OP, OPS and SOP all match. But we never had to research OPTS, POTS, STOP or STOPS because we didn't have T.
Do you see how this data structure makes it very efficient? Once you have determined that you do not have letters on the rack to start a word, you do not need to examine vocabulary words starting from that beginning. If you have software but no T, you do not need to investigate POTSHERD or POTATO, POTASH or POTLATCH or POTABLE; all these expensive and fruitless searches go away very quickly.
Adaptation of the system to work with "wild" plates is quite simple; if you have OPS ?, then just run the search algorithm 26 times, on OPSA, OPSB, OPSC ... It should be fast enough to make it 26 times cheap (or do it 26 x 26 times if you have two spaces.)
This is the main algorithm used by professional Scrabble AI programs, although, of course, they also have to deal with things such as the position of the board, rack management, etc., which complicates the algorithms somewhat. This simple version of the algorithm will be fast enough to generate all possible words on the rack.
Do not forget that, of course, you only need to calculate trie / dawg once if the dictionary does not change over time. This can take a long time to create a trie from the dictionary, so you can do it once, and then figure out how to store the trie on disk in a form suitable for quick rebuild from disk.
You can optimize memory usage by building DAWG from trie. Note that there are many repetitions, because in English many words end the same way, just as many words begin the same way. Three do a great job of sharing nodes at the beginning, but with the lousy job of sharing them at the end. For example, you may notice that the "S $ without children" pattern is extremely common and turns trie into:
^root^ / | \ OPS | | / \ P$ OOT / \ | | | T$ | T$ P$ O | \ | | | \ \| / P$ \ |/ | \ | / \ | / \ | / \| / |/ | S$
Saving a whole bunch of nodes. And then you can notice that now two words end with OP $ -S $, and two words end with T $ -S $, so you can compress it further:
^root^ / | \ OPS | | / \ P$ O \ T / \| \ | | | \| | | O | T$ | \ | P$ \ | / \| / | / |/ S$
And now we have a minimal DAWG for this dictionary.
Further reading:
http://dl.acm.org/citation.cfm?id=42420
http://archive.msdn.microsoft.com/dawg1
http://www.gtoal.com/wordgames/scrabble.html