Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Актуализирайте стойността на първичния ключ с помощта на рамката на обекта

Имам докторска степен. в cs - в областта на базите данни, така че този отговор ще бъде малко по-различен от гледната точка на програмистите. С цялото уважение към Оливър Ханапи, ключът може и понякога се променя, ако не е сурогатен ключ. напр. Естествен ключ или композитен ключ. Например. Възможно е да промените вашия SSN в САЩ. Но много програмисти през годините биха смятали това за непроменен ключ и биха го използвали като такъв. Много по-често се променя съставен първичен ключ, съставен от външни ключове.

Имам работа с база данни, която има троична връзка. По-конкретно три обекта (като външните ключове са заместващи първични ключове в съответните им таблици). Въпреки това, за да се запази връзката между два обекта, докато промяната на третия обект изисква промяна на част от първичния ключ на таблицата на пресичане (наричана още таблица за чисто присъединяване в MSDN). Това е валиден дизайн и може да бъде подобрен само чрез премахване на таблицата за пресичане на троични връзки и замяната й с две таблици на двоични връзки (които може да имат свои собствени сурогатни ключове). EF ще се справи добре с това. Тази промяна в дизайна ще направи модел (Много->много)->много или Родител1-Родител2 -> Дете-внук (ако това не е ясно, прочетете примера по-долу). Рамката на обекта би работила добре с това, тъй като всяка връзка наистина е една към много отношения. Но това е луд дизайн от гледна точка на DB. Нека ви покажа пример защо.

Имайте предвид, че курсът, класната стая и инструкторът са свързани един с друг в клас. Класът може да включва:CourseID, ClassroomID, InstructorID като външни ключове и да съдържа съставен първичен ключ, включително и трите. Въпреки че е ясен, сбит троичен модел (3-посочна връзка), бихме могли да го разделим на бинарни връзки. Това ще даде две пресечни таблици. Добавянето на сурогатни ключове би удовлетворило EF, както следва:

Клас (SurrogateKeyClass , Ид. на инструктор , CourseID )

ClassRoomUsed(SurrogateKeyClassroomUsed , SurrogateKeyClass , ClassRoomID )

Проблемът с този дизайн е, че можем да имаме един и същ курс и инструктор, свързани няколко пъти, което предишният модел избягва. За да избегнете този проблем, можете да добавите ограничение в базата данни за уникалност на двете полета за идентификация, но защо бихте искали да правите това, когато имате работа само със сурогатни ключове за начало? Това решение обаче би работило най-добре, доколкото мога да кажа. Това обаче не е логически дизайн на база данни поради неестественото уникално ограничение, изисквано в DB.

НО, ако не искате да промените базата си данни или не можете да промените базата си данни, ето второ решение :Таблиците за пресичане/асоцииране са точно това, връзки, свързващи две или повече единици заедно. Ако някоя се промени, изтрийте асоциацията и създайте отново нова, която има съответните външни ключове (свойства за навигация). Това означава, че няма да ви бъде позволено да изисквате дъщерни субекти в нито една от връзките, но това е изключително често.

Бих предложил Entity Framework (в бъдеще) да позволи на тези от нас, които могат да проектират елегантен модел на DB, да променят части от ключове в таблици за пресичане/асоцииране, когато пожелаем!

Друг безплатен пример:

Помислете за асоциация на ученик, курс, оценка. Студентите са свързани с курс чрез оценка. Обикновено това е много към много асоциация между студент и курс с допълнително поле в таблицата за асоцииране, наречена клас (таблиците за асоцииране имат данни за полезен товар като клас, таблиците за пресичане нямат полезен товар и се споменават в MSDN като чисти таблици за присъединяване на лизинг на едно място):

Студент (Идентификатор на ученик , ....)

Курс (CourseID , ...)

Приемане (Идентификатор на ученик , CourseID , оценка)

Ако някой направи грешка при въвеждане на данни от падащо меню и постави ученик в грешен клас, искате той да го промени по-късно, като избере отново падащото меню и избере различен курс. Във фонов режим ще трябва да изтриете EF обекта от таблицата Taking и да го създадете отново, без да губите оценка, ако има такава. Просто промяна на външния ключ CourseID изглежда като по-добра алтернатива. Измислете си собствена асоциация, ако тази изглежда измислена, но като професор беше естествено за мен.

Заключение:Когато имате низ от връзки, може да е по-добре да не позволявате каскадно и/или променяне на FK, но съществуват разумни/логически сценарии, където е необходимо, дори ако не се препоръчва като най-добра практика в общо /em> .

Този проблем може да се прояви със следните изключения в зависимост от това дали променяте съответно свойството за навигация или ключовото свойство в модела:

Възникна нарушение на ограничението за референтна цялост:Свойството на първичния ключ, което е част от ограничението за референтна цялост, не може да бъде променено, когато зависимият обект е Непроменен, освен ако не е зададен на основния обект на асоциацията. Основният обект трябва да бъде проследен и да не се маркира за изтриване.

Свойството 'X' е част от ключовата информация за обекта и не може да бъде променено.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ограничение за размера на индекса от 900 байта в дължината на знаците

  2. Как да изпълня IF...THEN в SQL SELECT?

  3. Различно представяне на UUID в Java Hibernate и SQL Server

  4. Отстраняване на проблеми с репликацията на транзакции на SQL Server

  5. Превключване на дял в SQL Server (T-SQL)