2009-04-17 3 views
2

У меня есть две таблицы в моей базе данных SQL:Компания против Сотрудника ID дилеммой

Компания:

  • ID (автоинкремент)
  • имя
  • адрес
  • ...

сотрудников:

  • ID (автоинкремент)
  • company_id
  • internal_id
  • имя
  • Lastname

Проблема заключается в том, что я хотел бы иметь идентификатор сотрудника (internal_id), который по отношению к компании они принадлежат. Я получил эту дилемму, так как я действительно искал, что было бы самым чистым способом ее реализации.

Один из вариантов заключается в том, чтобы просто создать своего рода SELECT MAX (internal_id) FROM сотрудников WHERE company_id = X, но проблема в том, что если мне удастся удалить последнего сотрудника, следующий будет создан с идентификатором следующий.

Любые идеи или предложения?

PD: Причина, по которой я хочу сделать это, заключается в том, что я не хочу, чтобы пользователь из компании X создал сотрудника, например ID = 2000, в то время как последний сотрудник, созданный в его компании, был, скажем, 1532 это обычно происходит в системе, в которой компании Y и Z также создают сотрудников в одной и той же системе. Я хочу, чтобы этот ID не использовался как foreign_key, но для его использования для внутренних (даже документов или отчетов).

PD2: В этом случае сотрудники никогда не придется менять компании

+2

Нужно переписать или уточнить ваш вопрос, в настоящий момент это не имеет никакого смысла. –

+0

@chad: Я думаю, что он хочет создать 2 auto_increment в таблице employee - id и internal_id -, где internal_id имеет сферу деятельности компании. так: компания1, компания2; сотрудник1 в компании1 id: 1, internal_id 1; employee2 at company1 id: 2, internal_id 2; employee3 at company2 id: 3, internal_id 1; сотрудник4 в компании2 id: 4, internal_id 2. беспорядок, но нет строк в комментариях !? – stefs

+0

Так что же такое земное различие, если есть пробел?Всегда будут возникать пробелы из-за ухода людей, отката транзакций и т. Д. – HLGEM

ответ

3

Здесь много вопросов о создании идентификаторов или номеров бизнеса, которые не связаны с первичными ключами.

В вашем случае я бы создал столбец в таблице компании «NextEmployeeID». Затем при создании нового сотрудника просто получить значение и увеличить его.

Теперь я оставляю это для вас, чтобы выяснить, что произойдет, если сотрудник меняет компании. :-)

+0

Я бы порекомендовал то же самое – stefs

+0

гарантирует, что вы не создадите проблемы параллелизма –

+1

, если сотрудник меняет компании, он получает новый внутренний идентификатор новой компании и всех строк в зависимости от перерыва internal_id :), но: вы могли бы удалить и повторно вставить сотрудника, потеряв все старые данные. или вы можете «деактивировать» сотрудника в старой компании, а не удалять его, добавляя ссылку на старое «я» в новой emp-записи, чтобы вы могли отслеживать его в разных компаниях. wheooo! – stefs

0

Вы никогда не должны удалить строку из реляционной базы данных. Вы должны истечь этого сотрудника (IE, Set Employee.ActiveFlag = 0)

Итак, если у вас был внутренний_ID (int) и сделал (SELECT MAX (internal_Id) +1 FROM Employees WHERE Company_Id = [parameterCompanyID]), то это будет работать нормально.

+0

Нет, у вас были бы проблемы с параллелизмом, это очень плохая техника. – HLGEM

+0

Спасибо Nathan, Я не знал этого aproach .. даже Rails или любая инфраструктура просто УДАЛИТЬ строки после удаления. Даже если интересно, почему вы это сделаете? У вас есть больше ссылок на этот вопрос? – Guillermo

+0

Это называется «мягкое удаление». Я не знаю или не реализую Rails, но на CakePHP есть «SoftDeletableBehavior», который делает это автоматически. –

0

Если вы собираетесь использовать идентификатор сотрудника как fk, вы действительно хотите удалить его и всю свою работу в БД? Создайте поле статуса у сотрудника и установите для него «A» ctive или «I». EmployeeID лучше, если он остается уникальным для всех компаний, поэтому просто дайте ему автоинкремент. Никогда не позволяйте пользователям видеть идентификаторы, позволяйте им видеть только имена.

также не называют идентификаторы колонок, CompanyID или EmployeeID, будут более читабельными и удобными для поиска.

0

Почему бы не использовать GUID для вашей внутренней_иды? Таким образом, вы всегда можете просто вставлять, не опасаясь столкновения с идентификаторами.

Вы не сможете избежать аномалии удаления, учитывая текущую структуру, но вы действительно не должны делать это так, как вы предлагаете. Чтобы надежно получить «следующий номер», вам придется заблокировать стол, и это вызовет все виды плохого. Возможно, вы можете реализовать какое-то мягкое удаление для сотрудников, поскольку они, как правило, идут и приходят иногда в любом случае. :)

+0

Я думаю, что это было бы полезно, например, если вы создавали приложение для компании с начислением заработной платы. Каждая компания хотела бы, чтобы их сотрудник был пронумерован по-разному и не заботился о ПК вашего db. –

+0

Я никогда не позволяю пользователям видеть внутренние идентификаторы, они имеют дело с Именами, я имею дело с идентификаторами –

+0

GUIDs? вы имеете в виду что-то вроде COMPANYID-EMPLOYEEID .. Я думал об этом, но это не то, что я хочу. Я чувствую, что каждая компания чувствует, что у них есть «их» часть системы. Представьте, что вы создаете своего первого сотрудника, а затем имеете 1110-7343? ? Это то, что вы имеете в виду BTW? – Guillermo

12

Нет, не делайте этого! Это создаст много проблем в вашей базе данных (вы должны беспокоиться о проблемах параллелизма между прочим), чтобы решить что-то, что НЕ является прообразом и на самом деле правильно спроектировано. Идентификатор должен быть бессмысленным, а пробелы несущественны. Вам понадобится уникальный индекс в комбинации employeeid/companyid, чтобы гарантировать, что ни один сотрудник не будет назначен нескольким компаниям.

Ваш идентификатор сотрудника должен быть тем, что никогда не нужно менять. Если вы сделаете какой-то глупый идентификатор компании, а компания A выкупит компанию B и станет компанией C, вам придется изменить все идентификаторы и все связанные таблицы. В вашем текущем проекте вам нужно только обновить балансовую единицу, но не соответствующие таблицы.

+0

+1 Пользователь только видит имена, а база данных использует только идентификаторы –

+3

К сожалению, «глупые» фирменные идентификаторы иногда являются действительным бизнес-требованием –

+0

Я отредактировал сообщение, чтобы уточнить, почему я думаю, что мне это нужно, я знаю, это похоже на меня, но я не знаю wnat использовать этот internal_id для чего-нибудь еще! – Guillermo

4

Создайте отдельную таблицу:

CREATE TABLE t_identity (company INT NOT NULL PRIMARY KEY, id INT NOT NULL) 

и вопрос:

INSERT 
INTO t_identity (@company, 1) 
ON DUPLICATE KEY UPDATE 
SET  id = id + 1 

перед установкой нового сотрудника.

+0

+1, @Guillermo, если у вас должны быть идентификаторы, основанные на компании, это лучший способ пойти. Я думаю, что уникальные идентификаторы сотрудников во всех компаниях проще, и не имеет значения, не позволяйте пользователю когда-либо видеть ID, он является «внутренним». Если они хотят номер сотрудника, дайте им другое поле, которое не является ключом или fk (например, поле имени), которое они могут видеть/контролировать. –

0

Я бы создал отдельную таблицу, как предложил Квасной, с компанией и текущим номером последовательности max. Но я бы обернул его в хранимый proc или UDF (делает ли MySQL UDF?), Который принимает компанию в качестве входных данных, увеличивает текущее значение и возвращает увеличивающееся значение.

0

Я предпочел бы создать 3 столбца для 3 переменных и позволить администратору изменять значения в базе данных! 1. КОРПОРАЦИЯ КОРПОРАЦИИ КОМПАНИИ (компанияCode, т.е. COMP) 2. ДЕПАРТАМЕНТ ОТДЕЛЕНИЯ КОМПАНИИ (depCode, т. Е. DEP) 3. СТОИМОСТЬ СТАРТА КОМПАНИИ (compVal ie 00000) Теперь При добавлении нового сотрудника я присоединился бы ко всем переменным и увеличил и обновил compVal ++ каждый раз! (т. Е. COMP-DEP-0001) или Мы также можем добавить дату() с идентификатором сотрудника