如何在 mysql DB 中存储用户的语言知识(150 多种语言)

use*_*861 1 mysql database-design

我网站上的用户必须能够选择他们知道的语言(英语、德语等),所以我有一个languages包含 150 种语言(id、名称)和表users(id 和许多其他字段)的表。

网站的访问者必须能够通过他们的语言知识来搜索用户。例如,他们可能正在寻找擅长英语、德语和法语的人。

我无法解决这个问题。如果我创建一个language_knowledge包含字段 id、language_id 和 user_id 的表,那么我将能够找到知道一种特定语言(比如英语)的用户,但我需要找到知道的用户,例如,英语和德语。

我该怎么做呢?

Vér*_*ace 5

这是您使用连接表的经典情况(可以在此处找到基于此的小提琴。它比原始答案晚得多 - 语言表的 PRIMARY KEY 的更好候选者!。

CREATE TABLE user
(
  user_id INT,
  user_name VARCHAR(25),
  PRIMARY KEY (user_id)
);

CREATE TABLE language
(
  iso_code CHAR(2),  -- or whatever you want the PRIMARY KEY to be.
  language_name VARCHAR(30),
  PRIMARY KEY (iso_code)
);

CREATE TABLE user_language
(
  ul_user_id INT,
  ul_iso_code CHAR(2),
  PRIMARY KEY (ul_user_id, ul_iso_code),
  FOREIGN KEY (ul_user_id) REFERENCES user (user_id),
  FOREIGN KEY (ul_iso_code) REFERENCES language (iso_code)
);  
Run Code Online (Sandbox Code Playgroud)

我忘了提到 FOREIGN KEY必须指向引用表中的 PRIMARY KEY 或 UNIQUE KEY(而不是其他任意字段)。

为了完整起见,您应该在两个连接字段上放置一个 PRIMARY KEY。这将有助于查询响应时间并避免多次输入相同数据。无论您的应用程序做什么,始终尝试在数据库中强制执行 RI(参照完整性)。

该查询展示了如何获得用户ID和名称的人谁知道这两个英语和德语。

SELECT ul_user_id
    , user_name
FROM user_language ul 
    INNER JOIN language l ON ul.ul_iso_code = l.iso_code 
    INNER JOIN user u ON u.user_id = ul.ul_user_id
WHERE l.language_name IN (
    'English'
    , 'German'
    )
GROUP BY ul_user_id, user_name 
HAVING COUNT(*) = 2;
Run Code Online (Sandbox Code Playgroud)

HAVING COUNT(*) = 2条款将结果仅限于同时了解两种语言的人。如果该IN (...)条款有 3 种不同的语言,则您需要修改该HAVING条款以反映这一点,例如: HAVING COUNT(*) = 3