MySQL:了解映射表

| 当为具有多对多关系的业务目录构建类别导航系统时,我知道创建映射表是一种好习惯。 类别表(CategoryId,CategoryName) 业务表(BusinessId,BusinessName) 类别映射表(BusinessId,CategoryId) 当我将类别表和业务表合并以创建映射表时,这是否会给我一个包含所有可能的业务和类别关系的表? 我有800个类别和1000个企业列表。那可以给我一张包含800,000种可能关系的表吗?如果是这样,我将如何只关注存在的关系?我是否必须遍历所有列表(800,000个),将其标记为是或否? 我对此一直感到非常困惑,因此我们将不胜感激。     
已邀请:
        使用多对多关系时,唯一可行的解​​决方法是使用映射表。 假设我们有一所有师生的学校,一个学生可以有多名老师,反之亦然。 所以我们做了3张桌子
student
  id unsigned integer auto_increment primary key
  name varchar

teacher
  id unsigned integer auto_increment primary key
  name varchar

link_st
  student_id integer not null
  teacher_id integer not null
  primary key (student_id, teacher_id)
学生表将有1000条记录 教师表将有20条记录 link_st表将具有与链接一样多的记录(不是20x1000,但仅用于实际链接)。 选拔 您选择例如每位老师使用的学生人数:
SELECT s.name, t.name 
FROM student
INNER JOIN link_st l ON (l.student_id = s.id)   <--- first link student to the link-table
INNER JOIN teacher t ON (l.teacher_id = t.id)   <--- then link teacher to the link table.
ORDER BY t.id, s.id
通常,您应该在此处始终使用
inner join
。 建立连结 当您将老师分配给学生时(反之亦然)。 您只需要做:
INSERT INTO link_st (student_id, teacher_id) 
   SELECT s.id, t.id 
   FROM student s 
   INNER JOIN teacher t ON (t.name = \'Jones\')
   WHERE s.name = \'kiddo\'
这有点误用了内部联接,但是只要名称是唯一的,它就可以工作。 如果您知道ID,当然可以直接插入这些ID。 如果名称不是唯一的,则将失败,不应使用。 如何避免重复链接 避免重复链接非常重要,如果有重复链接,则会发生各种不良情况。 如果要防止在链接表中插入重复的链接,可以在链接上声明一个“ 4”索引(推荐)
ALTER TABLE link_st
  ADD UNIQUE INDEX s_t (student_id, teacher_id); 
或者,您可以在insert语句中进行检查(不建议这样做,但是可以)。
INSERT INTO link_st (student_id, teacher_id) 
  SELECT s.id, t.id
  FROM student s
  INNER JOIN teacher t ON (t.id = 548)
  LEFT JOIN link_st l ON (l.student_id = s.id AND l.teacher_id = t.id)
  WHERE (s.id = 785) AND (l.id IS NULL)
如果该数据尚未在“ 7”表中,则将仅选择548、785;如果该数据已在link_st中,则不返回任何内容。因此它将拒绝插入重复的值。 如果您有一所台式学校,则取决于一个学生是否可以入读多所学校(不太可能,但假设),而老师是否可以入读多所学校。很有可能。
table school
  id unsigned integer auto_increment primary key
  name varchar

table school_members
  id id unsigned integer auto_increment primary key
  school_id integer not null
  member_id integer not null
  is_student boolean not null
您可以像这样列出学校中的所有学生:
SELECT s.name
FROM school i
INNER JOIN school_members m ON (i.id = m.school_id)
INNER JOIN student s ON (s.id = m.member_id AND m.is_student = true)
    
           当我加入类别表和   业务表创建映射   这会给我一张桌子吗   包含所有可能的业务   和类别关系? 是。   我是否必须遍历所有列表(800,000个),将其标记为是或否? 不,您需要使用“ 10”子句设置连接条件。
SELECT <columns> FROM categories as c 
INNER JOIN mapping AS m
    ON m.CategoryId = c.CategoryId
INNER JOIN businesses as b
    ON m.BusinessId = b.BusinessId
    
        尝试为多对多或一对多关系建模时,应使用映射表。 例如,在地址簿应用程序中,特定联系人可能属于零,一或多个类别。如果您将业务逻辑设置为联系人只能属于一个类别,则可以按以下方式定义您的联系人:
Contact
--------------
contactid (PK)
name
categoryid (FK)

Category
--------------
categoryid (PK)
categoryname
但是,如果您希望允许一个联系人拥有多个电子邮件地址,请使用映射表:
Contact
--------------
contactid (PK)
name

Category
--------------
categoryid (PK)
categoryname

Contact_Category
--------------
contactid (FK)
categoryid (FK)
然后,您可以使用SQL检索联系人分配给的类别的列表: 从类别a,联系人b,联系人类别c中选择一个类别名称,其中a.categoryid = c.categoryid和b.contactid = c.contactid和b.contactid = 12345;
select a.categoryname 
from Category a
inner join Contact_Category c on a.categoryid=c.categoryid
inner join Contact b on b.contactid=c.contactid
where b.contactid=12345;
    
        您只需将真正的关系放在映射表中。因此,某家公司的平均业务分为两类,那么在您的示例中,映射表中将只有2000条记录,而不是800,000条 \“当我将类别表和业务表合并以创建映射表时\”,不要将这两个表合并以创建映射表。您创建一个实际的物理表。     

要回复问题请先登录注册