【12】表关系(表的对应关系)

1. 一对一

1.1 主键一对一

  1. 场合:基础信息、附加信息,需要有相同的用户编号。
  2. 举例:Person表和Address表具有相同的PersonId,Person表做主表,Address表做子表;Address表的主键是Person表的外键。
  3. 创建表:
	CREATE TABLE Person
	(
	  person_Id INT NOT NULL, -- PK
	  person_Name VARCHAR(50),
	  PRIMARY KEY(person_Id)
	);
	CREATE TABLE Address
	(
	  person_Id INT NOT NULL, -- PK , FK
	  address VARCHAR(200),
	  PRIMARY KEY(person_Id),
	  FOREIGN KEY(person_Id) REFERENCES Person(person_Id)
	);
  1. 添加数据
	INSERT INTO Person(person_Id,person_Name) VALUES (1,'张三');
	INSERT INTO Person(person_Id,person_Name) VALUES (2,'李四');
	SELECT * FROM Person;

  	INSERT INTO Address(person_Id,address) VALUES (1,'解放路55号');
  	INSERT INTO Address(person_Id,address) VALUES (2,'文化东路55号');
  	SELECT * FROM Address;
  1. 关联查询:
    连接条件:从表的外键 等于 主表的主键
	SELECT * FROM Person , Address
		      WHERE Address.`person_Id` = Person.`person_Id`;
		      
	SELECT * FROM Person p, Address a 
		      WHERE a.`person_Id` = p.`person_Id`;

1.2 外键一对一

  1. 场合:每个用户有唯一的学历信息。一个学历的编号只能被使用一次。
  2. 举例:Address表做主表,Person表做子表;Person表中的address_Id是Address表的外键,并且是唯一的。
  3. 创建表:
	CREATE TABLE Address2
	(
	   address_Id INT NOT NULL, -- PK 
	   address_content VARCHAR(200),
	   PRIMARY KEY(address_Id)
	);
	CREATE TABLE Person2
	(
	   person_Id INT NOT NULL, -- PK
	   person_Name VARCHAR(50),
	   address_Id INT NOT NULL UNIQUE, -- FK , UNIQUE 表示唯一,每一个address_Id只能用一次
	   PRIMARY KEY(person_Id),
	   FOREIGN KEY(address_Id) REFERENCES Address2(address_Id)
	);
  1. 添加数据
	INSERT INTO Address2(address_Id,address_content) VALUES (1,'青岛路33号');
	INSERT INTO Address2(address_Id,address_content) VALUES (2,'和平路158号');
	INSERT INTO Address2(address_Id,address_content) VALUES (3,'香山大街7号');
	
	SELECT * FROM Address2;
	
	INSERT INTO Person2(person_Id,person_Name,address_Id) VALUES (1,'张三',1);
	INSERT INTO Person2(person_Id,person_Name,address_Id) VALUES (2,'李四',2);
	INSERT INTO Person2(person_Id,person_Name,address_Id) VALUES (3,'李四',3);
	
	SELECT * FROM Person2;
  1. 关联查询:
    连接条件:从表的外键 等于 主表的主键
	SELECT * FROM Person2 p, Address2 a WHERE p.`address_Id` = a.`address_Id`;

2.一对多(多对一)

  1. 场合:一张表是主表,另一张表是子表,主表与子表的对应关系不受唯一性控制;
  2. 举例:Grade表和Student表,Grade表做主表,Student表做子表;Student表的Grade_Id是Student表的外键,引用的是Grade表中的主键Grade_Id。
  3. 创建表:
	CREATE TABLE IF NOT EXISTS Grade
	(
	   Grade_Id INT NOT NULL, -- 主键
	   Grade_Name VARCHAR(50) NOT NULL ,
	   PRIMARY KEY(Grade_Id)
	)
	
	CREATE TABLE Student(  
	  Stu_No INT NOT NULL ,
	  Stu_Name VARCHAR(50) NOT NULL ,
	  Stu_Age INT DEFAULT 15 ,
	  Stu_Sex CHAR(2) DEFAULT '男' ,
	  Stu_Birthday DATE ,
	  Grade_Id INT , -- 外键
	  PRIMARY KEY (Stu_No),
	  FOREIGN KEY (Grade_Id) REFERENCES Grade(Grade_Id)
	) 
	
  1. 添加数据
	INSERT INTO Grade(Grade_Name) VALUES ('一年级');
	INSERT INTO Grade(Grade_Name) VALUES ('二年级');
	INSERT INTO Grade(Grade_Name) VALUES ('三年级');
	
	SELECT * FROM Grade;
	
	INSERT INTO Student(Stu_Name,Stu_Age,Stu_Birthday,Grade_Id) 
		VALUES ('张三',21,'1997-1-1',1);
	INSERT INTO Student(Stu_Name,Stu_Age,Stu_Birthday,Grade_Id) 
		VALUES ('李四',22,'1996-4-1',2);
	INSERT INTO Student(Stu_Name,Stu_Age,Stu_Birthday,Grade_Id) 
		VALUES ('王五',19,'1999-11-11',2);
  1. 关联查询:
    连接条件:从表的外键 等于 主表的主键
	SELECT * FROM Grade INNER JOIN Student
	  ON Grade.`Grade_Id` = Student.`Grade_Id`;
	  
	SELECT s.`Stu_No`,s.`Stu_Name`,g.`Grade_Name` FROM Student s INNER JOIN Grade g
	  ON s.`Grade_Id` = g.`Grade_Id`
	    WHERE s.`Stu_Sex` = '女';

3. 多对多

3.1 学生、课程、成绩类的问题

  • 一个学生可以选择多门课程,一门课程可以被多个学生选;
  • 使用中间表(成绩表)记录学生和课程之间的对应关系。
  1. 建表
	CREATE TABLE Student(  
	  Stu_No INT NOT NULL,
	  Stu_Name VARCHAR(50) NOT NULL ,
	  PRIMARY KEY (Stu_No),
	) ;

	CREATE TABLE Course
	(
	  Course_Id INT NOT NULL ,
	  Course_Name VARCHAR(50) NOT NULL ,
	  PRIMARY KEY(Course_Id)
	);

	CREATE TABLE Result
	(
	  Id INT NOT NULL ,
	  Stu_No INT NOT NULL ,
	  Course_Id INT NOT NULL ,
	  Result DECIMAL(5,2) ,
	  PRIMARY KEY(Id)
	);

	ALTER TABLE Result ADD CONSTRAINT FK_Result_Student
		FOREIGN KEY(Stu_No) REFERENCES Student(Stu_No);
	ALTER TABLE Result ADD CONSTRAINT FK_Result_Course
		FOREIGN KEY(Course_Id) REFERENCES Course(Course_Id);
  1. 插入数据
	INSERT INTO Student(Stu_No,Stu_Name) VALUES (1,'张三');
	INSERT INTO Student(Stu_No,Stu_Name) VALUES (2,'李四');
	INSERT INTO Student(Stu_No,Stu_Name) VALUES (3,'王五');
	INSERT INTO Student(Stu_No,Stu_Name) VALUES (4,'赵柳');
	INSERT INTO Student(Stu_No,Stu_Name) VALUES (5,'张无忌');
	SELECT * FROM Student;
	
	INSERT INTO Course(Course_Id,Course_Name) VALUES (1,'Java');
	INSERT INTO Course(Course_Id,Course_Name) VALUES (2,'SEO');
	INSERT INTO Course(Course_Id,Course_Name) VALUES (3,'PS');
	SELECT * FROM Course;
	
	INSERT INTO Result(id,Stu_No,Course_Id,Result) VALUES (1,1,2,90);
	INSERT INTO Result(id,Stu_No,Course_Id,Result) VALUES (2,2,1,75.5);
	INSERT INTO Result(id,Stu_No,Course_Id,Result) VALUES (3,3,1,39);
	INSERT INTO Result(id,Stu_No,Course_Id,Result) VALUES (4,2,2,70);
	
	SELECT * FROM Result;
  1. 具体实现
  • 查询学号、姓名、课程编号、课程名称、成绩
    • 学号(Result、Student)
    • 姓名(Student)
    • 课程编号(Result、Course)
    • 课程名(Course)
    • 成绩(Result)
	SELECT s.`Stu_No`,s.`Stu_Name`,c.`Course_Id`,c.`Course_Name`,r.`Result` 
	  FROM Result r 
	    RIGHT JOIN Student s ON s.`Stu_No` = r.`Stu_No`
	    LEFT JOIN Course c ON r.`Course_Id` = c.`Course_Id`
		WHERE c.Course_Id IS NULL -- 没选课
		-- WHERE c.Course_Id is not null and r.`Result` IS NULL -- 选课了,没考试
	    Order by s.`Stu_No`
  • 查询没有被选的课程信息
	SELECT * FROM Course 
		WHERE Course_Id NOT IN (SELECT DISTINCT Course_id FROM Result);

3.2 用户、角色、权限类的问题

  • 用户:(User)当前系统中注册的用户信息
  • 角色:(Role)把特定的权限,组成一个角色,将角色分配给用户。可以把角色看做是一组权限的组合体。
  • 权限:(Permission)在多用户计算机系统中,权限是指某个特定的用户具有特定的系统资源使用权力,权限是对每个用户能够做什么事情,进行的具体约束。
  • 用户与角色的关系:多对多,一个用户可以具备多个角色,一个角色可以分配给多个用户。
  • 角色与权限的关系:多对多,一个角色包含多个权限,一个权限可以赋给多个角色。
  1. 建表
   # 用户表
   CREATE TABLE t_User
   (
     User_Id INT NOT NULL,
     User_Name VARCHAR(50) NOT NULL,
     PRIMARY KEY(User_Id)
   );
   # 角色表
   CREATE TABLE t_Role
   (
     Role_Id INT NOT NULL,
     Role_Name VARCHAR(50) NOT NULL,
     PRIMARY KEY(Role_Id)
   );
   # 用户角色表
   CREATE TABLE t_RoleUser
   (
      RU_Id INT NOT NULL,
      User_Id INT,
      Role_Id INT,
      PRIMARY KEY(RU_Id),
      FOREIGN KEY(User_Id) REFERENCES t_User(User_Id),
      FOREIGN KEY(Role_Id) REFERENCES t_Role(Role_Id)
   );
   # 权限表
   CREATE TABLE t_Permission
   (
      Permission_Id INT NOT NULL,
      Permission_Name VARCHAR(50) NOT NULL,
      PRIMARY KEY(Permission_Id)
   );
   # 权限角色表
   CREATE TABLE t_PermissionRole
   (
      PR_Id INT NOT NULL,
      Permission_Id INT,
      Role_Id INT,
      PRIMARY KEY (PR_Id),
      FOREIGN KEY(Permission_Id) REFERENCES t_Permission(Permission_Id),
      FOREIGN KEY(Role_Id) REFERENCES t_Role(Role_Id)
   );
  1. 插入数据
    。。。。。。。。。。。。

  2. 具体实现
    查询指定用户的角色列表
    查询指定用户的权限列表
    查询指定用户的所有角色和所有权限
    。。。。。。。。。

猜你喜欢

转载自blog.csdn.net/Spectre_win/article/details/88538507