私はこのようなものを保存する必要があります:
mac_1 string
mac_2 string
mac_3 string
mac_4 string
4 macs (または 1 mac) でレコードを検索する機能。各レコードを反復すると、値が最良の選択肢ではなくなりますか? MySQL MATCH AGAINST はサーバーに大きな負荷がかかります。全文検索が使えません :( この種のデータを保存するための簡単でエレガントな方法を教えてください。
私はこのようなものを保存する必要があります:
mac_1 string
mac_2 string
mac_3 string
mac_4 string
4 macs (または 1 mac) でレコードを検索する機能。各レコードを反復すると、値が最良の選択肢ではなくなりますか? MySQL MATCH AGAINST はサーバーに大きな負荷がかかります。全文検索が使えません :( この種のデータを保存するための簡単でエレガントな方法を教えてください。
このフィールドを構成要素に分割し、それらをスレーブ テーブルに格納する必要があります。これには次の利点があります。
効率的な等検索を行うには、4 つのフィールドすべてにインデックスを付けるだけで十分です。
問題は、4 つのフィールドすべてをカバーする 1 つの複合インデックスを使用できるか、または 4 つの個別のインデックスを使用できるかです。
mac_1
他のフィールドで検索するかどうかで常に検索する場合は、 で複合インデックスを作成するだけ{mac_1, ...}
です。AND 条件を使用しているため、このインデックスを使用すると、1 回のインデックス シークで行を見つけることができます。InnoDB テーブルはクラスター化されており、クラスター化されたテーブルのセカンダリインデックスの「シーク」には、実際には 2 つのシーク (インデックス シーク自体 + プライマリ/クラスタリング インデックス シーク) が必要になる場合があることに注意してください。をカバーすることでこれを回避できますが、ストレージの増加とキャッシュ効率の低下という代償を払う可能性があります。
また、オプティマイザーがこれらのインデックスを実際に利用できるように、クエリを作成するときに巧妙になりすぎないように注意してください。必要に応じて、動的 SQL をためらわないでください。
別の設計は、「子」テーブルにmac
値が含まれる外部キーによって接続された2つのテーブルを持つことです....
CREATE TABLE p (
p_id INT PRIMARY KEY
-- Other fields...
);
CREATE TABLE c (
p_id INT REFERENCES p (p_id),
mac varchar(50), -- Or whatever type is appropriate.
PRIMARY KEY (p_id, mac)
);
...そして、次のようmac
に (たとえば) の値に 接続されている親行をクエリします。'aaa' AND 'bbb' AND 'ccc'
SELECT p.p_id -- Other fields...
FROM p JOIN c ON p.p_id = c.p_id
WHERE mac = 'aaa' OR mac = 'bbb' OR mac = 'ccc'
GROUP BY p.p_id -- Other fields...
HAVING COUNT(*) = 3;
mac
ところで、この設計では、必要に応じて親行ごとに 4 つを超える値を使用できます。
残念ながら、MySQL には最も洗練されたクエリ オプティマイザがありません。そのため、この設計にコミットする前に現実的な量のデータでテストしてください。