sql >> Databasteknik >  >> RDS >> Sqlserver

Uppdatera primärnyckelvärdet med hjälp av enhetsramverket

Jag har en Ph.D. i cs - inom området databaser, så det här svaret kommer att vara lite annorlunda än ett programmerares perspektiv. Med all respekt för Oliver Hanappi, en nyckel kan och ändras ibland om den inte är en surrogatnyckel. T.ex. En naturlig nyckel eller en sammansatt nyckel. Till exempel. Det är möjligt att få ditt SSN ändrat i USA. Men många programmerare genom åren skulle betrakta detta som en oföränderlig nyckel och använda den som sådan. Det är mycket vanligare att ändra en sammansatt primärnyckel som består av främmande nycklar.

Jag har att göra med en databas som har en ternär relation. Närmare bestämt tre enheter (med främmande nycklar som surrogat-primärnycklar i sina respektive tabeller). Men för att bevara relationen mellan två enheter samtidigt som den tredje enheten ändras krävs ändra del av skärningstabellen (även kallad en ren sammanfogningstabell på MSDN) primärnyckeln. Detta är en giltig design och kan bara förbättras genom att ta bort den ternära relationsskärningstabellen och ersätta den med två binära relationstabeller (som kan ha sina egna surrogatnycklar). EF skulle klara det här bra. Denna designändring skulle göra en (Många->många)->många eller Förälder1-Förälder2 -> Barn-barnbarnsmodell (om det inte är tydligt läs exemplet nedan). Entity framework skulle fungera bra med detta eftersom varje relation verkligen är en till många relation. Men det är en galen design ur ett DB-perspektiv. Låt mig visa dig ett exempel på varför.

Tänk på att kurs, klassrum och instruktör är associerade med varandra i en klass. Klass kan innehålla:CourseID, ClassroomID, InstructorID som främmande nycklar och innehålla en sammansatt primärnyckel inklusive alla tre. Även om en tydlig, koncis ternär modell (3-vägsrelation) kan vi dela upp den i binära relationer. Detta skulle ge två skärningstabeller. Att lägga till surrogatnycklar skulle tillfredsställa EF enligt följande:

Klass(SurrogateKeyClass , Instruktörs-ID , Kurs-ID )

ClassRoomUsed(SurrogateKeyClassroomUsed , SurrogateKeyClass , Klassrums-ID )

Problemet med denna design är att vi skulle kunna ha samma kurs och instruktör kopplad flera gånger, vilket den tidigare modellen undviker. För att undvika detta problem kan du lägga till en begränsning i databasen för att de två ID-fälten ska vara unika, men varför skulle du vilja göra detta när du bara har att göra med surrogatnycklar till att börja med? Men den här lösningen skulle fungera så gott jag kan säga. Detta är dock inte en logisk databasdesign på grund av den onaturliga unika begränsningen som krävs i DB.

MEN om du inte vill ändra din databas eller inte kan ändra din databas, här är en andra lösning :Skärnings-/associationstabeller är just det, länkar som länkar samman två enheter eller fler. Om en ändras, ta bort kopplingen och återskapa en ny som har lämpliga främmande nycklar (navigeringsegenskaper). Det betyder att du inte kommer att tillåtas att kräva underordnade enheter i någon av relationerna, men det är extremt vanligt.

Jag skulle föreslå att Entity Framework (i framtiden) tillåter de av oss som kan designa en elegant DB-modell att ändra delar av nycklar i intersektions-/associationstabeller när vi vill!

Ett annat exempel gratis:

Överväg en student-, kurs-, betygsförening. Studenter kopplas till en kurs via ett betyg. Vanligtvis är detta många till många kopplingar mellan student och en kurs med ett extra fält i associationstabellen som kallas betyg (associationstabeller har nyttolastdata som betyg, skärningstabeller har ingen nyttolast och hänvisas till i MSDN som rena sammanfogningstabeller på hyra på ett ställe):

Student(Student-ID , ....)

Kurs(Kurs-ID , ...)

Tar (StudentID , Kurs-ID , betyg)

Om någon gör ett datainmatningsfel från en rullgardinsmeny och placerar en elev i fel klass, vill du att de ändrar det senare genom att välja rullgardinsmenyn igen och välja en annan kurs. I bakgrunden måste du ta bort EF-objektet från Taking-tabellen och återskapa det utan att förlora ett betyg om det finns ett. Ändra helt enkelt den främmande nyckeln Kurs-ID verkar vara ett bättre alternativ. Kom på en egen förening om den här verkar konstruerad, men som professor var det naturligt för mig.

Slutsats:När du har en rad relationer kan det vara bättre att inte tillåta kaskad och/eller ändra FK, men det finns rimliga/logiska scenarier där det behövs, även om det inte rekommenderas som en bästa praxis allmänt .

Detta problem kan visa sig med följande undantag beroende på om du ändrar navigationsegenskapen respektive nyckelegenskapen i modellen:

En överträdelse av referensintegritetsbegränsning inträffade:En primärnyckelegenskap som är en del av referensintegritetsbegränsning kan inte ändras när det beroende objektet är oförändrat om det inte ställs in på föreningens huvudobjekt. Huvudobjektet måste spåras och inte markeras för radering.

Egenskapen 'X' är en del av objektets nyckelinformation och kan inte ändras.



  1. Skapa bara en tabell om den inte finns i MariaDB

  2. anslut med klausul i regex_substr

  3. Hur MAKETIME() fungerar i MariaDB

  4. Är det möjligt att ange parametrar för tabell- eller kolumnnamn i Prepared Statements eller QueryRunner.update()?