Programing

데이터베이스 디자인에 외래 키가 정말로 필요합니까?

lottogame 2020. 8. 12. 22:07
반응형

데이터베이스 디자인에 외래 키가 정말로 필요합니까?


내가 아는 한, 외래 키 (FK)는 프로그래머가 데이터를 올바른 방식으로 조작하도록 돕는 데 사용됩니다. 프로그래머가 실제로이 작업을 이미 올바른 방식으로 수행하고 있다고 가정하면 외래 키 개념이 정말로 필요합니까?

외래 키에 대한 다른 용도가 있습니까? 여기에 뭔가 빠졌나요?


외래 키는 데이터 수준에서 참조 무결성을 적용하는 데 도움이됩니다. 또한 일반적으로 기본적으로 색인이 생성되기 때문에 성능도 향상됩니다.


외래 키는 프로그래머가 ON DELETE CASCADE. 즉, 사용자를 포함하는 하나의 테이블과 주문 등을 포함하는 다른 테이블이있는 경우 사용자를 삭제하면 해당 사용자를 가리키는 모든 주문이 자동으로 삭제 될 수 있습니다.


외래 키없이 데이터베이스를 디자인하는 것은 상상할 수 없습니다. 그것들이 없으면 결국 실수를하고 데이터의 무결성을 손상시킬 수밖에 없습니다.

엄격히 말하면 필수 는 아니지만 이점은 엄청납니다.

나는 FogBugz 가 데이터베이스에 외래 키 제약 조건을 가지고 있지 않다고 확신 합니다. 나는 Fog Creek Software 팀이 불일치가 발생하지 않도록 코드를 구조화 하는 방법을 듣고 싶습니다 .


FK 제약이없는 데이터베이스 스키마는 안전 벨트없이 운전하는 것과 같습니다.

언젠가는 후회하게 될 것입니다. 설계 기본 사항과 데이터 무결성에 약간의 추가 시간을 소비하지 않는 것은 나중에 골치 아픈 일을 확실하게하는 확실한 방법입니다.

응용 프로그램에서 그렇게 엉성한 코드를 수락 하시겠습니까? 멤버 개체에 직접 액세스하고 데이터 구조를 직접 수정했습니다.

왜 이것이 현대 언어에서 어렵고 용납 할 수 없다고 생각 합니까?


예.

  1. 그들은 당신을 정직하게 유지합니다
  2. 새로운 개발자를 정직하게 유지합니다.
  3. 넌 할 수있어 ON DELETE CASCADE
  4. 테이블 간의 링크를 자체 설명하는 멋진 다이어그램을 생성하는 데 도움이됩니다.

개인적으로 저는 외래 키가 테이블 간의 관계를 공식화하기 때문에 선호합니다. 귀하의 질문은 프로그래머가 참조 무결성을 위반하는 데이터를 도입하지 않는다고 전제한다는 것을 알고 있지만 최선의 의도에도 불구하고 데이터 참조 무결성이 위반되는 사례를 너무 많이 보았습니다!

사전 외래 키 제약 (선언적 참조 무결성 또는 DRI라고도 함)은 트리거를 사용하여 이러한 관계를 구현하는 데 많은 시간을 소비했습니다. 선언적 제약으로 관계를 공식화 할 수 있다는 사실은 매우 강력합니다.

@John-다른 데이터베이스는 외래 키에 대한 인덱스를 자동으로 만들 수 있지만 SQL Server는 그렇지 않습니다. SQL Server에서 외래 키 관계는 제약 일뿐입니다. 외래 키에 대한 인덱스를 별도로 정의해야합니다 (유용 할 수 있음).

편집 : IMO, ON DELETE 또는 ON UPDATE CASCADE를 지원하는 외래 키 사용이 반드시 좋은 것은 아닙니다. 실제로는 데이터의 관계를 기반으로 삭제시 캐스케이드가 신중하게 고려되어야한다는 사실을 발견했습니다. 예를 들어 이것이 괜찮을 수있는 자연 부모-자식이 있거나 관련 테이블이 조회 값 집합 인 경우입니다. 계단식 업데이트를 사용하면 한 테이블의 기본 키를 수정할 수 있음을 의미합니다. 이 경우 테이블의 기본 키가 변경되어서는 안된다는 일반적인 철학적 불일치가 있습니다. 키는 본질적으로 일정해야합니다.


프로그래머가 실제로이 작업을 이미 올바른 방식으로 수행하고 있다고 가정합니다.

그런 가정을하는 것은 매우 나쁜 생각 인 것 같습니다. 일반적으로 소프트웨어는 엄청나게 버그가 많습니다.

그리고 그것이 정말로 요점입니다. 개발자는 일을 제대로 할 수 없으므로 데이터베이스가 잘못된 데이터로 채워지지 않도록하는 것은 좋은 일입니다.

이상적인 환경에서는 자연 조인이 열 이름과 일치하는 대신 관계 (예 : FK 제약 조건)를 사용합니다. 이것은 FK를 더욱 유용하게 만들 것입니다.


외래 키가 없으면 다른 테이블의 두 레코드가 관련되어 있음을 어떻게 알 수 있습니까?

나는 당신이 언급하는 것은 참조 무결성, 즉 기존의 부모 레코드없이 자식 레코드를 만들 수없는 경우라고 생각합니다. 이것들은 종종 외래 키 제약으로 알려져 있습니다.하지만 외래 키의 존재와 혼동해서는 안됩니다. 첫 번째 장소.


외래 키가 없으면 이점이 있습니까? 엉뚱한 데이터베이스를 사용하지 않는 한 FK는 설정하기가 그리 어렵지 않습니다. 그렇다면 왜 그들을 피하는 정책을 가지고 있습니까? 열이 다른 열을 참조하는 명명 규칙을 갖는 것과 데이터베이스가 실제로 해당 관계를 확인하고 있다는 것을 아는 것은 다른 것입니다.


데이터베이스에 의해 시행되는 외래 키 제약 에 대해 이야기하고 있다고 가정 합니다 . 아마도 이미 외래 키를 사용하고있을 것이고, 데이터베이스에 그것에 대해 말하지 않았을 것입니다.

프로그래머가 실제로이 작업을 이미 올바른 방식으로 수행하고 있다고 가정하면 외래 키 개념이 정말로 필요합니까?

이론적으로는 그렇지 않습니다. 그러나 버그가없는 소프트웨어는 없었습니다.

애플리케이션 코드의 버그는 일반적으로 그렇게 위험하지 않습니다. 버그를 식별하고 수정하면 애플리케이션이 다시 원활하게 실행됩니다. 그러나 버그로 인해 중단 된 데이터가 데이터베이스에 들어 오도록 허용하는 경우 문제가 발생합니다! 데이터베이스의 손상된 데이터를 복구하는 것은 매우 어렵습니다.

FogBugz 의 미묘한 버그로 인해 손상된 외래 키가 데이터베이스에 기록 될 수 있는지 고려하십시오 . 버그를 수정하고 버그 수정 릴리스에서 고객에게 신속하게 수정 사항을 푸시하는 것이 쉬울 수 있습니다. 그러나 수십 개의 데이터베이스에서 손상된 데이터를 어떻게 수정해야합니까? 외래 키의 무결성에 대한 가정이 더 이상 유지되지 않기 때문에 올바른 코드가 갑자기 깨질 수 있습니다.

웹 애플리케이션에서는 일반적으로 데이터베이스와 대화하는 프로그램이 하나만 있으므로 버그로 인해 데이터가 손상 될 수있는 곳은 한 곳뿐입니다. 엔터프라이즈 응용 프로그램에는 동일한 데이터베이스에 대해 말하는 여러 독립 응용 프로그램이있을 수 있습니다 (데이터베이스 셸로 직접 작업하는 사람은 말할 것도 없음). 모든 애플리케이션이 항상 그리고 영원히 버그없이 동일한 가정을 따르도록 할 수있는 방법은 없습니다.

제약 조건이 데이터베이스에 인코딩 된 경우 버그로 인해 발생할 수있는 최악의 상황은 사용자에게 일부 SQL 제약 조건이 충족되지 않았다는 추악한 오류 메시지가 표시되는 것 입니다. 이는 데이터를 엔터프라이즈 데이터베이스로 전송하는 것 보다 훨씬 선호되며,이 경우 모든 애플리케이션이 중단되거나 모든 종류의 잘못되거나 오해의 소지가있는 출력이 발생합니다.

Oh, and foreign key constraints also improves performance because they are indexed by default. I can't think of any reason not to use foreign key constraints.


FKs are very important and should always exist in your schema, unless you are eBay.


I think some single thing at some point must be responsible for ensuring valid relationships.

For example, Ruby on Rails does not use foreign keys, but it validates all the relationships itself. If you only ever access your database from that Ruby on Rails application, this is fine.

However, if you have other clients which are writing to the database, then without foreign keys they need to implement their own validation. You then have two copies of the validation code which are most likely different, which any programmer should be able to tell is a cardinal sin.

At that point, foreign keys really are neccessary, as they allow you to move the responsibility to a single point again.


Foreign keys allow someone who has not seen your database before to determine the relationship between tables.

Everything may be fine now, but think what will happen when your programmer leaves and someone else has to take over.

Foreign keys will allow them to understand the database structure without trawling through thousand of lines of code.


As far as I know, foreign keys are used to aid the programmer to manipulate data in the correct way.

FKs allow the DBA to protect data integrity from the fumbling of users when the programmer fails to do so, and sometimes to protect against the fumbling of programmers.

Suppose a programmer is actually doing this in the right manner already, then do we really need the concept of foreign keys?

Programmers are mortal and fallible. FKs are declarative which makes them harder to screw up.

Are there any other uses for foreign keys? Am I missing something here?

Although this is not why they were created, FKs provide strong reliable hinting to diagramming tools and to query builders. This is passed on to end users, who desperately need strong reliable hints.


They are not strictly necessary, in the way that seatbelts are not strictly necessary. But they can really save you from doing something stupid that messes up your database.

It's so much nicer to debug a FK constraint error than have to reconstruct a delete that broke your application.


They are important, because your application is not the only way data can be manipulated in the database. Your application may handle referential integrity as honestly as it wants, but all it takes is one bozo with the right privileges to come along and issue an insert, delete or update command at the database level, and all your application referential integrity enforcement is bypassed. Putting FK constraints in at the database level means that, barring this bozo choosing to disable the FK constraint before issuing their command, the FK constraint will cause a bad insert/update/delete statement to fail with a referential integrity violation.


I think about it in terms of cost/benefit... In MySQL, adding a constraint is a single additional line of DDL. It's just a handful of key words and a couple of seconds of thought. That's the only "cost" in my opinion...

Tools love foreign keys. Foreign keys prevent bad data (that is, orphaned rows) that may not affect business logic or functionality and therefor go unnoticed, and build up. It also prevents developers who are unfamiliar with the schema from implementing entire chunks of work without realizing they're missing a relationship. Perhaps everything is great within the scope of your current application, but if you missed something and someday something unexpected is added (think fancy reporting), you might be in a spot where you have to manually clean up bad data that's been accumulating since the inception of the schema without a database enforced check.

The little time it takes to codify what's already in your head when you're putting things together could save you or someone else a bunch of grief months or years down the road.

The question:

Are there any other uses for foreign keys? Am I missing something here?

It is a bit loaded. Insert comments, indentation or variable naming in place of "foreign keys"... If you already understand the thing in question perfectly, it's "no use" to you.


Entropy reduction. Reduce the potential for chaotic scenarios to occur in the database. We have a hard time as it is considering all the possiblilites so, in my opinion, entropy reduction is key to the maintenance of any system.

When we make an assumption for example: each order has a customer that assumption should be enforced by something. In databases that "something" is foreign keys.

I think this is worth the tradeoff in development speed. Sure, you can code quicker with them off and this is probably why some people don't use them. Personally I have killed a number of hours with NHibernate and some foreign key constraint that gets angry when I perform some operation. HOWEVER, I know what the problem is so it's less of a problem. I'm using normal tools and there are resources to help me work around this, possibly even people to help!

The alternative is allow a bug to creep into the system (and given enough time, it will) where a foreign key isn't set and your data becomes inconsistent. Then, you get an unusual bug report, investigate and "OH". The database is screwed. Now how long is that going to take to fix?


You can view foreign keys as a constraint that,

  • Help maintain data integrity
  • Show how data is related to each other (which can help in enforcing business logic and rules)
  • If used correctly, can help increase the efficiency with which the data is fetched from the tables.

We don't currently use foreign keys. And for the most part we don't regret it.

That said - we're likely to start using them a lot more in the near future for several reasons, both of them for similar reasons:

  1. Diagramming. It's so much easier to produce a diagram of a database if there are foreign key relationships correctly used.

  2. Tool support. It's a lot easier to build data models using Visual Studio 2008 that can be used for LINQ to SQL if there are proper foreign key relationships.

So I guess my point is that we've found that if we're doing a lot of manual SQL work (construct query, run query, blahblahblah) foreign keys aren't necessarily essential. Once you start getting into using tools, though, they become a lot more useful.


The best thing about foreign key constraints (and constraints in general, really) are that you can rely on them when writing your queries. A lot of queries can become a lot more complicated if you can't rely on the data model holding "true".

In code, we'll generally just get an exception thrown somewhere - but in SQL, we'll generally just get the "wrong" answers.

In theory, SQL Server could use constraints as part of a query plan - but except for check constraints for partitioning, I can't say that I've ever actually witnessed that.


Foreign keys had never been explicit (FOREIGN KEY REFERENCES table(column)) declared in projects (business applications and social networking websites) which I worked on.

But there always was a kind of convention of naming columns which were foreign keys.

It's like with database normalization -- you have to know what are you doing and what are consequence of that (mainly performance).

I am aware of advantages of foreign keys (data integrity, index for foreign key column, tools aware of database schema), but also I am afraid of using foreign keys as general rule.

Also various database engines could serve foreign keys in a different way, which could lead to subtle bugs during migration.

Removing all orders and invoices of deleted client with ON DELETE CASCADE is the perfect example of nice looking, but wrong designed, database schema.


Yes. The ON DELETE [RESTRICT|CASCADE] keeps developers from stranding data, keeping the data clean. I recently joined a team of Rails developers who did not focus on database constraints such as foreign keys.

Luckily, I found these: http://www.redhillonrails.org/foreign_key_associations.html -- RedHill on Ruby on Rails plug-ins generate foreign keys using the convention over configuration style. A migration with product_id will create a foreign key to the id in the products table.

Check out the other great plug-ins at RedHill, including migrations wrapped in transactions.

참고URL : https://stackoverflow.com/questions/18717/are-foreign-keys-really-necessary-in-a-database-design

반응형