如何思考和组织双向多对多数据库。

huangapple go评论69阅读模式
英文:

How to think about and organize a Many-to-Many bidirectional database

问题

我相信最适合我的数据应该是一个双向的多对多数据库(我正在使用SQL和Java)。我试图表示员工和工作职位之间的关系。每个员工都有一个唯一的标识符,可以担任一个或多个职位,而每个职位可以有任意数量的员工。复杂的部分是双方都有优先级排名:对于每个员工,他们将有一个有序列表,列出他们能够胜任的职位,而对于每个职位,也会有一个优先级较高的员工的有序列表。

举个例子,假设我们有七名员工(id为00-06)可以参与给定班次,有两个职位,监管员和收银员。需要一个监管员,以及两到四名收银员。

  • employee00 只担任收银员职位
  • employee01 只担任收银员职位
  • employee02 只担任收银员职位
  • employee03 同时担任监管员和收银员职位,其中监管员具有优先级
  • employee04 同时担任监管员和收银员职位,其中监管员具有优先级
  • employee05 同时担任监管员和收银员职位,其中收银员具有优先级
  • employee06 只担任监管员职位

有五名员工(00-05)符合担任收银员职位,四名员工(03-06)符合担任监管员职位。由于符合监管员职位的员工比收银员职位的员工少,而每个班次只需要一个监管员,调度软件将首先分配监管员职位。通常,系统会将优先级评定为 employee06 > employee03 = employee04 > employee05,这意味着只能担任监管员的employee06 将被分配到该班次的职位。

我的系统变得复杂是因为每个职位也有一个优先级排名。因此,如果监管员职位的优先级排名偏向于employee03(也许他们只是非常优秀,但是他们是新手,所以将他们也安排为收银员是合适的),那么他们将被安排在employee06之上。新的系统将优先级排名为employee03 > employee06 > employee04 > employee05

我的直觉是为每个职位创建一个表,其中包含员工id和在该职位内的相对优先级。一个员工id可以出现在多个表中,程序可以通过搜索该ID来整合表格,以获取员工可以填充的所有职位。还将有一个最终的员工表,列出了他们的姓名、联系信息以及调度程序不考虑的其他信息。

作为一个对数据库设计新手的问题是,这种思考问题的方式是否有效。

英文:

First, I am new to database management, so my terminology might be slightly incorrect.

I have data I believe would best fit into a many-to-many bidirectional database (I am using SQL with Java). I am trying to represent the relationship between employees and job positions. Each employee, identified by a unique id, can hold one or more positions, and each position can have any number of employees. The complicated part is that there is a priority ranking from both ends: for each employee, they will have an ordered list ranking of the positions they are capable of, and for each position, there will be an ordered list of prioritized employees.

For example, let's say we have seven employees (ids 00-06) available for a given shift, and two positions, supervisor and cashier. One supervisor is needed, and between two and four cashiers.

  • employee00 holds only the cashier position
  • employee01 holds only the cashier position
  • employee02 holds only the cashier position
  • employee03 holds both the supervisor and cashier position, with supervisor being prioritized
  • employee04 holds both the supervisor and cashier position, with supervisor being prioritized
  • employee05 holds both the supervisor and cashier position, with cashier being prioritized
  • employee06 holds only the supervisor position

There are five employees (00-05) who are qualified for cashier, and four employees (03-06) qualified for the supervisor position. Since there are fewer qualified supervisors than cashiers, and you need only one per shift, the scheduling software will assign the supervisor position first Typically, the system would rate the priority as employee06 > employee03 = employee04 > employee05, meaning that employee06 (who can only be a supervisor) would be assigned the position for that shift.

My system gets complicated because each position also has a priority ranking. So if the supervisor position's priority ranking favors employee03 (perhaps they are just really good but are new enough that it is appropriate to also put them as a cashier), they would be scheduled even above employee06. The new system would then have the priority ranked as employee03 > employee06 > employee04 > employee05.

My gut instinct is to make a table for each position, with columns for employee id and relative priority within the position. An employee id could be in multiple tables, and the program could compile the tables by searching for that ID to get all positions the employee can fill. There would be a final table of employees listing their names, contact information, and other stuff that is not taken into account by the scheduler.

My question, as someone new to database design, is if this is a valid way of thinking about the problem.

答案1

得分: 3

我建议使用一个桥接版本。

正如您在示例中所看到的,您可以轻松获取一个主管和两名收银员,并且优先级也已经建立。

RAND()保证不会总是选择相同的人,当然,如果您手头有足够的员工。

添加更多信息,如每个员工的工作日或他们的收入,可以完善结构:

CREATE TABLE employee(id_emp int PRIMARY KEY, employee_name varchar(50))
INSERT INTO employee VALUES (1,'Emp0'),(2,'Emp1'),(3,'Emp2'),(4,'Emp3'),(5,'Emp4'),(6,'Emp5'),(7,'Emp6')
CREATE TABLE position (id_pos int PRIMARY KEY, position_name varchar(50))
INSERT INTO position VALUES (1,'cashier'), (2,'supervisor')
CREATE TABLE Pos_EMP(emp_id int, pos_id int, prio int)
INSERT INTO Pos_EMP VALUES (1,1,1),(2,1,1),(3,1,1),(4,1,2),(4,2,1),(5,1,2),(5,2,1),(6,1,1),(6,2,2),(7,2,1)
WITH FIRST_Supervisor as (SELECT id_emp, employee_name, position_name 
  FROM employee e INNER JOIN Pos_EMP pe ON e.id_emp = pe.emp_id
  INNER JOIN position p ON p.id_pos = pe.pos_id
  WHERE pos_id = 2 ORDER BY prio, RAND() LIMIT 1)
  SELECT employee_name, position_name  FROM FIRST_Supervisor
  UNION ALL 
(SELECT  employee_name, position_name 
  FROM employee e INNER JOIN Pos_EMP pe ON e.id_emp = pe.emp_id
  INNER JOIN position p ON p.id_pos = pe.pos_id
  WHERE pos_id = 1 AND emp_id NOT IN ( SELECT id_emp FROM FIRST_Supervisor)  ORDER BY prio, RAND() LIMIT 2)
employee_name position_name
Emp4 supervisor
Emp5 cashier
Emp2 cashier

fiddle

英文:

I would suggest a bridge version.

As you see in the sample, you can easily get a supervisor and two cashiers and the priority is also build in.

The RAND() guaranties that not always are the same persons selected, that of course if you have enough employees at your hand.

Adding more information, like workdays for each employee, or how much they earn can refine the structure:

CREATE tABLE employee(id_emp int Primary Key, employee_name varchar(50))
INSERT INTO employee VALUES (1,'Emp0'),(2,'Emp1'),(3,'Emp2'),(4,'Emp3'),(5,'Emp4'),(6,'Emp5'),(7,'Emp6')
CREATE TABLE position (id_pos int PRIMARY KEY, position_name varchar(50))
INSERT INTO position VALUES (1,'cashier'), (2,'supervisor')
CREATE TABLE Pos_EMP(emp_id int, pos_id int, prio int)
INSERT INTO Pos_EMP VALUES (1,1,1),(2,1,1),(3,1,1),(4,1,2),(4,2,1),(5,1,2),(5,2,1),(6,1,1),(6,2,2),(7,2,1)
WITH FIRST_Supervisor as (SELECT id_emp,  employee_name, position_name 
  FROM employee e INNER JOIN Pos_EMP pe ON e.id_emp = pe.emp_id
INNER JOIN position p ON p.id_pos = pe.pos_id
WHERE pos_id = 2 ORDER BY prio, RAND() LIMIT 1)
  SELECT employee_name, position_name  FROM FIRST_Supervisor
  UNION ALL 
(SELECT  employee_name, position_name 
  FROM employee e INNER JOIN Pos_EMP pe ON e.id_emp = pe.emp_id
INNER JOIN position p ON p.id_pos = pe.pos_id
WHERE pos_id = 1 AND emp_id NOT IN ( SELECT id_emp FROM FIRST_Supervisor)  ORDER BY prio, RAND() LIMIT 2)

employee_name position_name
Emp4 supervisor
Emp5 cashier
Emp2 cashier

fiddle

答案2

得分: 2

员工表 Employee: id, 员工姓名

职位表 Position: id, 职位名称

职级表 Ranking: id, 职级值

现在有一个多对多关系的员工-职位表

员工-职位表 EmployeePositions: id, 员工id, 职位id, 职级id

有了这个结构,您所描述的情况得到支持,因为一个员工可以拥有多个职位,每个职位都有对应的职级,使您可以完全掌控逻辑。

英文:

> Table Employee: id,employeeName

> Table Position:id,positionName

> Table Ranking: id,rankingValue

Now a Many to many table Employee-Position

Table EmployeePositions: id, idEmployee,idPosition,idRaking

With this structure the scenario you described is supported, given that an employee can have many positions each one Ranked, givin you full control over the logic.

huangapple
  • 本文由 发表于 2023年7月7日 05:00:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定