Sql 多对多表中的主键

Sql 多对多表中的主键,sql,postgresql,Sql,Postgresql,假设我有两个表,用户和语言 user (Table Name) ----------------- user_id (PK) user_name mobile ... .... language (Table Name) --------------------- lang_code (PK) lang_name ... .... 问题是,如果我想添加用户和语言表之间的关系(多对多),这是一种正确的方法吗 solution 1 user_language (Table Name) ----

假设我有两个表,用户和语言

user (Table Name)
-----------------
user_id (PK)
user_name
mobile
...
....

language (Table Name)
---------------------
lang_code (PK)
lang_name
...
....
问题是,如果我想添加用户和语言表之间的关系(多对多),这是一种正确的方法吗

solution 1

user_language (Table Name)
--------------------------
user_id (FK)
lang_code (FK)


or solution 2

user_language (Table Name)
--------------------------
user_id (PK)
lang_code (PK)


or solution 3

user_language (Table Name)
--------------------------
user_lang_id (PK)
user_id (FK)
lang_code (FK)
我看到很多人在多对多表上添加主键,但我认为这并不重要,而且浪费了空间。那么哪一个是正确的呢


顺便说一句,我个人使用PostgreSQL,我会选择解决方案4:

user_language --------------- user_id (FK) lang_code (FK) with composite PRIMARY KEY (user_id, lang_code) 用户语言 --------------- 用户id(FK) 语言代码(FK) 使用复合主键(用户id、语言代码)
我不认为在解决方案3中添加代理键(
user\u lang\u id
)真的会给模式增加任何价值,而只是添加另一个需要担心的列。主键是保持唯一性的一个好主意-如果没有它,您可以多次添加相同的用户id/lang\u代码组合。

(用户id,lang\u代码)
上组合主键是一种通用方法。如果您希望在另一个表中引用
user\u language
,或者如果您在此表中存储了一些其他属性,则可能需要代理PK。但是即使在这种情况下,您通常对<代码>(UsSeriID,LangyCal码)

复合主键(UsSyId,LangyCal码)都有唯一的约束,同时也都是外键。考虑一下昨天在A中发布的N:M关系的完整代码示例。你通常就是这么做的。@Ahmad是的,我就是这个意思。