2009-08-06 35 views
7

Tôi có một bộ 4 bảng mà tôi muốn tìm kiếm trên đó. Mỗi chỉ mục văn bản đầy đủ. Truy vấn có thể sử dụng mọi chỉ mục không?mySQL MATCH trên nhiều bảng

CREATE TABLE `categories` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 

CREATE TABLE `host_types` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `category_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`category_id`,`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=latin1; 


CREATE TABLE `hosts` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `host_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`host_id`,`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; 


CREATE TABLE `products` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `host_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `uid` varchar(10) default NULL, 
    `name` varchar(128) default NULL, 
    `keywords` text, 
    `description` text, 
    `price` decimal(10,2) default NULL, 
    `quantity` int(11) unsigned default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    FULLTEXT KEY `full_name` (`name`,`keywords`,`description`,`uid`) 
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; 

Đây là truy vấn của tôi;

SELECT categories.name AS category, 
    categories.id AS category_id, 
    host_types.name AS host_type, 
    host_types.id AS host_type_id, 
    hosts.name AS host, 
    hosts.id AS host_id, 
    products.name as name, 
    products.id AS product_id, 
    products.keywords as keywords, 
    products.description AS description, 
    products.quantity AS quantity, 
    products.price AS price, 
    products.uid as catalogue, 
    MATCH(categories.name, host_types.name, hosts.name, products.name, 
     products.keywords, products.description, products.uid) 
     AGAINST('search term') as score 
FROM products 
LEFT JOIN hosts ON products.host_id = hosts.id 
LEFT JOIN host_types ON hosts.host_id = host_types.id 
LEFT JOIN categories ON host_types.category_id = categories.id 
WHERE MATCH(categories.name, host_types.name, hosts.name, products.name, 
      products.keywords, products.description, products.uid) 
     AGAINST('search term') 
ORDER BY score DESC; 
  • categories.name == toàn văn - 1
  • host_types.name == toàn văn - 2
  • hosts.name == toàn văn - 3
  • products.name, products.keywords, products.description, products.uid == toàn văn - 4

Dưới đây là cấu trúc SQL của tôi, và Tôi đã sử dụng Truy vấn ở trên.

SELECT 
    categories.name AS category, 
    categories.id AS category_id, 
    host_types.name AS host_type, 
    host_types.id AS host_type_id, 
    hosts.name AS host, 
    hosts.id AS host_id, 
    products.name as name, 
    products.id AS product_id, 
    products.keywords as keywords, 
    products.description AS description, 
    products.quantity AS quantity, 
    products.price AS price, 
    products.uid as catalgue 
    MATCH(categories.name) AGAINST('search term') as cscore, 
    MATCH(host_types.name) AGAINST('search term') as htscore, 
    MATCH(hosts.name) AGAINST('search term') as hscore, 
    MATCH(products.name, products.keywords, products.description, products.uid) 
    AGAINST('search term') as score 
FROM products 
LEFT JOIN hosts ON products.host_id = hosts.id 
LEFT JOIN host_types ON hosts.host_id = host_types.id 
LEFT JOIN categories ON host_types.category_id = categories.id 
WHERE 
    MATCH(categories.name) AGAINST('search term') OR 
    MATCH(host_types.name) AGAINST('search term') OR 
    MATCH(hosts.name) AGAINST('search term') OR 
    MATCH(products.name, products.keywords, products.description, products.uid) 
    AGAINST('search term') 
ORDER BY score DESC 



     CREATE TABLE `categories` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 

CREATE TABLE `host_types` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `category_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`category_id`,`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=latin1; 


CREATE TABLE `hosts` (
    `id` int(5) unsigned NOT NULL auto_increment, 
    `host_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `name` varchar(64) default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `order` (`host_id`,`display_order`), 
    FULLTEXT KEY `full_name` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; 


CREATE TABLE `products` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `host_id` int(5) unsigned default NULL, 
    `display_order` int(5) unsigned default NULL, 
    `uid` varchar(10) default NULL, 
    `name` varchar(128) default NULL, 
    `keywords` text, 
    `description` text, 
    `price` decimal(10,2) default NULL, 
    `quantity` int(11) unsigned default NULL, 
    `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    FULLTEXT KEY `full_name` (`name`,`keywords`,`description`,`uid`) 
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; 
+2

+50 cho người trả lời câu hỏi này ... .. một cách chính xác – Dirk

+0

Trong một giây, có vẻ như anh ấy đang có một chương trình truy vấn dài-sql-truy vấn. –

+1

Tôi đã chỉnh sửa nó với hy vọng tìm được một câu hỏi ... đó có phải là một câu đố không? –

Trả lời

22
  • Bạn không thể xác định chỉ số toàn văn (hay bất kỳ loại index) trên nhiều bảng trong MySQL. Mỗi định nghĩa chỉ mục tham chiếu chính xác một bảng. Tất cả các cột trong chỉ mục toàn văn đã cho phải từ cùng một bảng.

  • Các cột được đặt tên làm đối số cho hàm MATCH() phải là một phần của chỉ mục toàn văn duy nhất. Bạn không thể sử dụng một cuộc gọi đến MATCH() để tìm kiếm tất cả các cột là một phần của tất cả chỉ mục toàn văn trong cơ sở dữ liệu của bạn.

  • Toàn văn chỉ mục chỉ các cột chỉ mục được xác định với các kiểu dữ liệu CHAR, VARCHARTEXT.

  • Bạn có thể xác định chỉ mục toàn văn trong mỗi bảng.

Ví dụ:

CREATE TABLE categories (
    id SERIAL PRIMARY KEY, 
    name VARCHAR(100), 
    FULLTEXT INDEX ftcat (name) 
); 

CREATE TABLE host_types (
    id SERIAL PRIMARY KEY, 
    category_id BIGINT UNSIGNED, 
    name VARCHAR(100), 
    FULLTEXT INDEX ftht (name) 
); 

CREATE TABLE hosts (
    id SERIAL PRIMARY KEY, 
    host_id BIGINT UNSIGNED, 
    category_id BIGINT UNSIGNED, 
    name VARCHAR(100), 
    FULLTEXT INDEX fthost (name) 
); 

CREATE TABLE products (
    id SERIAL PRIMARY KEY, 
    name VARCHAR(100), 
    keywords VARCHAR(100), 
    uid VARCHAR(100), 
    description VARCHAR(100), 
    quantity INTEGER, 
    price NUMERIC(9,2), 
    host_id BIGINT UNSIGNED, 
    FULLTEXT INDEX ftprod (name, keywords, description, uid) 
); 

Và sau đó bạn có thể viết một truy vấn có sử dụng mỗi chỉ số toàn văn tương ứng:

SELECT ... 
    MATCH(categories.name) AGAINST('search term') as cscore, 
    MATCH(host_types.name) AGAINST('search term') as htscore, 
    MATCH(hosts.name) AGAINST('search term') as hscore, 
    MATCH(products.name, products.keywords, products.description, products.uid) 
    AGAINST('search term') as score 
FROM products 
LEFT JOIN hosts ON products.host_id = hosts.id 
LEFT JOIN host_types ON hosts.host_id = host_types.id 
LEFT JOIN categories ON host_types.category_id = categories.id 
WHERE 
    MATCH(categories.name) AGAINST('search term') OR 
    MATCH(host_types.name) AGAINST('search term') OR 
    MATCH(hosts.name) AGAINST('search term') OR 
    MATCH(products.name, products.keywords, products.description, products.uid) 
    AGAINST('search term') 
ORDER BY score DESC; 
Các vấn đề liên quan