0

私はこのようなものを保存する必要があります:

mac_1 string
mac_2 string
mac_3 string
mac_4 string

4 macs (または 1 mac) でレコードを検索する機能。各レコードを反復すると、値が最良の選択肢ではなくなりますか? MySQL MATCH AGAINST はサーバーに大きな負荷がかかります。全文検索が使えません :( この種のデータを保存するための簡単でエレガントな方法を教えてください。

4

3 に答える 3

1

このフィールドを構成要素に分割し、それらをスレーブ テーブルに格納する必要があります。これには次の利点があります。

  • 行ごとに 4 mac の人為的な制限はありません。0 の場合も 10 の場合もありますが、挿入時に制限できます
  • スレーブテーブルを適切にインデックス化すると、検索が高速になります
于 2013-01-04T08:41:29.330 に答える
1

効率的な等検索を行うには、4 つのフィールドすべてにインデックスを付けるだけで十分です。

問題は、4 つのフィールドすべてをカバーする 1 つの複合インデックスを使用できるか、または 4 つの個別のインデックスを使用できるかです。

  • (ほとんど)常に検索する優勢な「最先端」がある場合は、その最先端で複合インデックスを作成するだけです。たとえば、mac_1他のフィールドで検索するかどうかで常に検索する場合は、 で複合インデックスを作成するだけ{mac_1, ...}です。AND 条件を使用しているため、このインデックスを使用すると、1 回のインデックス シークで行を見つけることができます。
  • リーディング エッジに多くのバリエーションがある場合は、すべてのフィールドに個別のインデックスを作成するだけです。これには最大 4 回のインデックス シークが必要ですが、それでもかなり高速です。

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;

[SQLフィドル]

macところで、この設計では、必要に応じて親行ごとに 4 つを超える値を使用できます。

残念ながら、MySQL には最も洗練されたクエリ オプティマイザがありません。そのため、この設計にコミットする前に現実的な量のデータでテストしてください。

于 2013-01-04T15:00:02.950 に答える