Избегайте дубликатов при разработке отношений «один ко многим»

Перерыл много тем, так и не понял. Извините, если это дублирующийся вопрос. Рассмотрим следующую установку.

1) Сотрудник => (ID, Имя)

2) Отдел => (ID,Имя,местонахождение,Клерк,Бухгалтер,Средний менеджер,Групповой менеджер,Региональный менеджер,Активный)

В отделе может быть много клерков, бухгалтеров, менеджеров среднего звена и так далее. Это просто сотрудники из таблицы Employee. Нужна лучшая схема базы данных (гибкая, например, добавление нового столбца, так как Divisional-Manager должно быть простым) для сущности отдела без дублирования данных, без аномалий обновления и без / меньше соединительных таблиц.

Заранее спасибо! :)


person RealWillyWoka    schedule 05.05.2011    source источник


Ответы (6)


Вам нужно что-то вроде этого;

сотрудник отдела ERD

CREATE TABLE department(
    dept_id      int    NOT NULL,
    dept_name    char(10)    NULL,
    CONSTRAINT PK1 PRIMARY KEY NONCLUSTERED (dept_id)
)
go


CREATE TABLE department_employee(
    id         int    NOT NULL,
    dept_id    int    NOT NULL,
    emp_id     int    NOT NULL,
    CONSTRAINT PK3 PRIMARY KEY NONCLUSTERED (id)
)
go


CREATE TABLE employee(
    emp_id      int    NOT NULL,
    emp_name    char(10)    NULL,
    CONSTRAINT PK2 PRIMARY KEY NONCLUSTERED (emp_id)
)
go


ALTER TABLE department_employee ADD CONSTRAINT Refdepartment1 
    FOREIGN KEY (dept_id)
    REFERENCES department(dept_id)
go

ALTER TABLE department_employee ADD CONSTRAINT Refemployee2 
    FOREIGN KEY (emp_id)
    REFERENCES employee(emp_id)
go
person mevdiven    schedule 05.05.2011
comment
НЕТ› Я не могу это увидеть. :( - person RealWillyWoka; 05.05.2011
comment
Нам действительно нужен идентификатор для Department_Employee? А также пропустил должность/звание, которое он занимает в этом отделе. ТАК, мы можем иметь мастер позиции/названия и включить его также в Department_employee. Кстати, спасибо за размещение объяснения в тексте, учитывая мою неспособность просмотреть изображение. - person RealWillyWoka; 05.05.2011
comment
Нет, вам не нужен этот идентификатор. Вы можете иметь dept_id и emp_id как PK этой таблицы. Должность/название является атрибутом этой таблицы Department_Employee. Вы можете создать таблицу POSITION (pos_id, pos_name) и иметь pos_id в таблице Department_employee как FK. - person mevdiven; 05.05.2011

У вас есть отношения «многие ко многим», поэтому вам нужна третья таблица ассоциаций (соединений) - вы не можете избежать этого.

DepartmentMember => (DepartmentId, EmployeeId, MembershipRole)

Почему ты не хочешь этого?

person Tim Rogers    schedule 05.05.2011
comment
Это означает, что мне также нужна таблица MembershipRole? - person RealWillyWoka; 05.05.2011
comment
MembershipRole — это просто значение дескриминатора, представляющее, является ли это клерком, менеджером и т. Д. Это может быть символ, целое число или varchar, что вы считаете самым простым. - person Tim Rogers; 05.05.2011

Отдел => (ID, ID сотрудника, местоположение, активный) Сотрудник => (ID сотрудника, имя, должность)

Я думаю, что это был бы гораздо лучший способ организовать ваши столы. Это предполагает, что актив является свойством отдела, в противном случае переместите его в таблицу сотрудников.

person soandos    schedule 05.05.2011
comment
В этом дизайне вы можете иметь только одного сотрудника в отделе. - person mevdiven; 05.05.2011
comment
не так... идентификатор сотрудника меняется..., идентификатор в сотруднике - это идентификатор сотрудника, отличный от идентификатора отдела - person soandos; 05.05.2011
comment
если вы поместите идентификатор сотрудника в таблицу отдела, у вас не может быть более одного сотрудника в отделе. Это факт... - person mevdiven; 05.05.2011
comment
soandos, создайте таблицы так, как вы объясняете, и попробуйте добавить записи, тогда вы поймете, почему. - person mevdiven; 05.05.2011
comment
Я сделал, и он работает просто отлично (в доступе, но это не должно иметь значения). пожалуйста, объясните, в чем, по-вашему, проблема. - person soandos; 05.05.2011
comment
выполненный запрос и предоставил правильные данные (используя приведенные выше таблицы: SELECT Department.ID, Department.EmployeeID, Department.location, Department.active, Employees.name2, Employees.postion FROM Department INNER JOIN Employees ON Department.EmployeeID = Employees. ID сотрудника; ) - person soandos; 05.05.2011
comment
@soandos - Вы хотите сказать, что таблица Department имеет составной первичный ключ? (идентификатор отдела и идентификатор сотрудника) - person RealWillyWoka; 05.05.2011
comment
Да, почему бы и нет? первичный строго не требуется, в худшем случае. если количество отделов небольшое, проще сделать так, чем создавать еще одну таблицу. - person soandos; 05.05.2011
comment
@soandos, остановись, подумай еще раз, а потом пиши. Таблица отделов не должна/не может/не должна иметь employee_id, даже если это составной ПК, и точка! Различные домены данных. У вас должно быть 3 стола. DEPT (dept_id), EMP (emp_id) и DEPT_EMP (dept_id, emp_id) - person mevdiven; 05.05.2011
comment
@soandos - я согласен с Мевдивеном. Это ужасно дублирует столбцы Location & Active, верно? :) - person RealWillyWoka; 05.05.2011

Предположим, что сотрудник может работать только в одном отделе. ЕСЛИ нет, то да, вам нужна третья таблица, чтобы избежать дублирования

Работник

ID, Name, EmployeeType, DepartmentID
(pk on ID, EmployeeType)

отделение

ID, Name, Active
person StevieG    schedule 05.05.2011
comment
Он плохо дублирует активное поле. - person RealWillyWoka; 05.05.2011

Должность/название очень сильно зависит от контекста отдела. Можно быть региональным менеджером в одном отделе и дополнительно занимать должность консультанта в другом отделе.

Тогда отдел и Сотрудник относятся ко многим. Сотрудник на позицию также является многими ко многим. Если вам нужна гибкость, например добавление нового заголовка для отдела, необходимы соединительные таблицы. Вы не можете этого избежать.

Вы можете обратиться к следующей структуре таблицы для справки:

Employee 
-----------------------
EmployeeID (PK)
EmployeeName
Active

Department 
-------------------------
DepartmentID (PK)
DepartmenName
Location

Position 
----------------------------
PositionID (PK)
PositionDescription (eg.Clerk, Accountant etc)

EmployeePosition 
----------------------------
EmployeeID  (FK to Employee.EmployeeID )
DepartmentID (FK to Department.DepartmentID)
PositionID (FK to Position.PositionID )

Если Должность/Название закреплено за Сотрудником, а не за Отделом, т.е. Сотрудник, который является клерком и может занимать эту должность в одном или нескольких отделах, как мы можем это сделать?

Вы имеете в виду, что в крайнем случае многие сотрудники могут иметь свои специальные звания? и они принадлежат многим отделам? Если да, предположим, что сотрудник с идентификатором 123 имеет специальное звание «Особенный» и относится к отделу информационных технологий, бухгалтерского учета и продаж. Сначала вы создаете этот титул (например, «Особенный») в таблице Position и получаете Position.PositionID.

Затем вы вставляете 3 записи для Employee.EmployeeID 123 в таблицу EmployeePosition, используя этот Position.PositionID и идентификатор отдела ИТ, учетную запись, отделы продаж.

person Ken Chan    schedule 05.05.2011
comment
В моем сценарии сотрудник может занимать разные должности. И положение в одном отделе совершенно отличается от другого. Итак, нужно использовать соединительные таблицы, верно? - person RealWillyWoka; 05.05.2011
comment
@soandos Должность/название очень сильно зависит от контекста отдела. Можно быть региональным менеджером в одном отделе и дополнительно занимать должность консультанта в другом отделе. - person RealWillyWoka; 05.05.2011
comment
Тогда отдел и Сотрудник относятся ко многим. Сотрудник на позицию также является многими ко многим. Если вам нужна гибкость, например добавление нового заголовка для отдела, необходимы соединительные таблицы. Вы не можете этого избежать. - person Ken Chan; 05.05.2011
comment
таким образом, это будет так: таблицы будут такими: Department=›(departmentID,departmentname,active) Employee=›(employeeID,name) Employeetodepartment=›(departmentID,employeeID,postion) - person soandos; 05.05.2011
comment
@soandos =› ага. Может быть, я также могу подумать о том, чтобы иметь мастер-таблицу для позиции/названия. - person RealWillyWoka; 05.05.2011
comment
@Ken - Большое спасибо за это. Мне любопытно узнать схему, если Должность/Название закреплено за Сотрудником, а не за Отделом. то есть сотрудник, который является клерком и может занимать эту должность в одном или нескольких отделах, как мы можем это сделать? - person RealWillyWoka; 05.05.2011
comment
@keevas: Добро пожаловать, я только что обновил свои ответы в ответ на ваш вопрос. - person Ken Chan; 05.05.2011

person    schedule
comment
Если вы хотите, чтобы определенный сотрудник мог работать в нескольких отделах, у вас будет Employee =>(ID,name, position_ID, Active) и Emp_dep_rel => (employee_ID, department_ID) - person bpgergo; 05.05.2011