正規化されたアプローチが必要な場合は、次のようになります。
wordLetters{
INT wordID,
CHAR[1] letter,
INT count,
PK(wordID, letter)
}
words{
INT wordID PK,
VARCHAR(255) word UNIQUE
}
しかし、このアプローチにはパフォーマンスの点で深刻な問題があります。つまり、ワードテーブルの全表スキャンが必要です。文字が多すぎないと仮定して、このアプローチを提案します。
words{
INT wordID PK,
VARCHAR(255) word UNIQUE,
INT cA KEY,
INT cB KEY,
...
INT cZ KEY,
KEY (cE, cT, cA, cO, cI, cN),
...
}
ルックアップクエリは長くなりますが、インデックスを効率的に使用し、とにかくPHPコードによって生成されます。
ユーザーが持っている場合は[a,n,t]、使用可能な単語を次のようにフェッチします。
SELECT word FROM words WHERE
cA <= 1 AND cB = 0 AND cC = 0 AND ... AND cY = 0 AND cZ = 0
「E」を必要としない単語は多くないため、このクエリは(おそらく)「ETAOIN」インデックスを使用します。
この時点で、パフォーマンスはデータベースでのみ使用可能なインデックスの選択に依存し、有用と見なされるインデックスをいつでも追加できます(実行時でも)。
データベースインデックスの場合:
通常のインデックスは、リスト上に適切なツリーが構築されたアイテムのソートされたリストであり、効率的な範囲ルックアップを可能にします(xからyまでのすべての要素を取得します)。
通常のインデックスは、そのソート順によって定義されます。並べ替えの順序は次のとおりです。最初にある列、次に別の列、次に別の列で並べ替えます。
たとえば、[E,T,A,O,I,N]インデックスにはすべての単語が並べ替えられます。最初に、を必要としないすべての単語、次にE1つを必要とするEすべての単語、次に2つを必要とするすべての単語E...。同じ量のEsを必要とする単語がソートされます。最初に、を必要としないTすべての単語、次にそれを1回必要とするすべての単語、次に2つTのsを必要とするすべての単語...。同じ数のEsとTsを必要とする単語のうち、必要のない単語Aが最初に来ます。
Eデータベースが、またはaを必要とせず、多くても1つの「X」を必要としないすべての単語をフェッチするように求められた場合、データベースはTこのインデックスを使用して最初の2つの要件を満たし、範囲内のすべての単語をチェックできますE=0, T=0。
特定の選択は、英語で最も頻繁に使用される12文字を頻度で並べ替えるETAOIN SHRDLUETAOINというフレーズに基づいています。つまり、このインデックスを使用する場合は、可能な限り多くの単語を除外する必要があります。
例を使用しますRSTLNE。Rこのインデックスは、プレーヤーにsがない場合に使用されSます。ルックアップをベンチマークすると、特定の各インデックスを使用することでどれだけの時間が節約されたかがわかります。
クエリを使用EXPLAIN EXTENDEDして、特定のクエリごとに考慮され、その後使用されるインデックスと、除外されると予想される行数を確認できます。元。:
EXPLAIN EXTENDED
SELECT word FROM words
WHERE cA=0 AND cB<=1 AND cC=0 AND ...