0

我需要存储这样的东西:

mac_1 string
mac_2 string
mac_3 string
mac_4 string

能够通过 4 个 mac(或 1 个 mac)搜索记录。迭代每条记录和值会不会是最好的选择?MySQL MATCH AGAINST 将在服务器上产生沉重的负载。我不能使用全文搜索:(您能否建议一种简单而优雅的方式来存储此类数据?

4

3 回答 3

1

您应该将此字段拆分为其组成部分并将它们存储在从表中。这将有以下好处:

  • 没有人为限制每行 4 个 mac。可以是0,也可以是10,但是可以在插入时限制
  • 如果你正确索引从表,搜索会很快
于 2013-01-04T08:41:29.330 回答
1

为什么不将所有字段的串联存储为另一个字段:

mac_1 string
mac_2 string
mac_3 string
mac_4 string
mac_full string
于 2013-01-04T08:42:19.407 回答
1

对于有效的等价搜索,索引所有 4 个字段就足够了。

问题是您是否可以使用一个涵盖所有 4 个字段的复合索引,或 4 个单独的索引:

  • 如果您(几乎)总是在其上搜索一个主要的“前沿”,那么只需使用该前沿创建一个复合索引。例如,如果您总是搜索mac_1是否搜索其他字段,只需在{mac_1, ...}. 由于您使用的是 AND 条件,因此该索引将使您能够在单个索引查找中找到该行。
  • 如果您有许多领先优势的变体,只需在所有字段上创建单独的索引。这将需要多达 4 次索引查找,但应该仍然相当快。

请注意,InnoDB 表是聚集的,并且聚集表的二级索引上的“查找”实际上可能需要 2 次查找(索引查找本身 + 主/聚集索引查找)。您可以通过覆盖来避免这种情况,但可能会以增加存储空间和降低缓存效率为代价。

在构造查询时也要注意不要太聪明,这样优化器才能真正利用这些索引。如果需要,不要回避动态 SQL。


另一种设计是让两个表通过外键连接,其中“子”表将包含mac值....

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 回答