기본 키 / 외래 키 명명 규칙 [닫힘]


95

개발 그룹에서는 기본 및 외래 키의 명명 규칙에 대해 격렬한 논쟁이 있습니다. 우리 그룹에는 기본적으로 두 가지 학파가 있습니다.

1:

Primary Table (Employee)   
Primary Key is called ID

Foreign table (Event)  
Foreign key is called EmployeeID

또는

2 :

Primary Table (Employee)  
Primary Key is called EmployeeID

Foreign table (Event)  
Foreign key is called EmployeeID

어떤 열에도 테이블 이름을 복제하지 않는 것을 선호합니다 (따라서 위의 옵션 1을 선호합니다). 개념적으로는 속성 이름에 개체 이름을 사용하지 않는 다른 언어의 많은 권장 사례와 일치합니다. 외래 키 EmployeeID(또는 Employee_ID더 좋을 수도 있음)의 이름을 지정 하면 독자에게 그것이IDEmployee 테이블 열 .

다른 일부는 열 이름이 데이터베이스 전체에서 동일하도록 테이블 이름이 접두어로 붙은 기본 키의 이름을 지정하는 옵션 2를 선호합니다. 그 점을 알지만 이제는 기본 키와 외래 키를 시각적으로 구분할 수 없습니다.

또한, 나는 당신이 개체와 그 개체의 속성이나 속성으로 컬럼과 테이블을 생각하면, 당신은의 ID 속성으로 생각하기 때문에, 열 이름에 테이블 이름을 가지고 중복 생각 Employee하지 EmployeeID직원 의 속성. 나는 그의 것을 내 동료에게 가지 않는다 PersonAge또는 PersonGender이다. 나는 그에게 그의 나이가 무엇인지 묻습니다.

그래서 제가 말했듯이, 그것은 격렬한 논쟁이며 우리는 그것에 대해 계속해서 계속합니다. 새로운 관점을 얻고 싶습니다.



1
나는 10 개 이상의 유사한 질문을 읽었고 마침내 여기에 상위 3 개의 답변이 좋다는 것을 발견했다 : stackoverflow.com/a/465146/781695
user

참고 사항 : 선택 2는 'Natural Join'을 허용합니다. 도대체 'Employee.ID를 EmployeeID'로 추가하여 선택 1에서 여전히 수행하지 않겠습니까? 그러나 더 나은 방법은 'ON Employee.ID = Event.EmployeeID'를 사용하여 'Join'하는 것 같습니다.
Leo

두 경우 모두 열 이름을 반복하기 때문에 하나 이상의 쿼리에서 별칭 (또는 'table_name.column_name')을 사용해야합니다.
Please_Dont_Bully_Me_SO_Lords

답변:


52

별로 중요하지 않습니다. 나는 선택 1과 선택 2 사이에 실질적인 차이가있는 시스템을 본 적이 없습니다.

Jeff Atwood는이 주제에 대한 훌륭한 기사를 가지고있었습니다. 기본적으로 사람들은 자신이 잘못 증명할 수없는 주제에 대해 가장 격렬하게 토론하고 논쟁합니다. 또는 다른 각도에서, 필리 버스터 스타일의 지구력 기반 최후의 주장을 통해서만 이길 수있는 주제.

하나를 선택하고 실제로 코드에 영향을 미치는 문제에 집중하도록 지시하십시오.

편집 : 재미를 원한다면 재귀 테이블 참조에 대해 방법이 우수한 이유를 길게 지정하십시오.


26
+1, 상식을 위해 ... 논쟁 할 더 중요한 사항이 있습니다. 그러니 내 방식대로하세요 (2 번 선택)
Charles Bretana

5
그리고 자체 참조 DRI의 경우 동일한 PK를 자체 참조하는 FK가 둘 이상인 경우 두 FK 열의 이름을 동일하게 지정할 수 없으므로 두 "표준"을 모두 위반해야합니다. 예 : EmployeeTable EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK 등 ...
Charles Bretana

75

두 열의 이름이 두 테이블 모두에서 동일한 경우 (컨벤션 # 2) SQL에서 USING 구문을 사용하여 입력 및 상용구 노이즈를 줄일 수 있습니다.

SELECT name, address, amount
  FROM employees JOIN payroll USING (employee_id)

관례 # 2를 찬성하는 또 다른 주장은 이것이 관계형 모델 이 설계된 방식이라는 것 입니다.

각 열의 중요성은 해당 도메인의 이름으로 레이블을 지정하여 부분적으로 전달됩니다.


4
SQL 구문과 의미는 실제로 어떻게 사용해야하는지에 대한 단서를 제공합니다. 예를 들어 USING 구문은 동일한 도메인의 열이 동일한 이름을 가져야 함을 의미하고, NULL = NULL-> NULL은 NULL이 "적용 할 수 없음"이 아니라 "알 수 없음"을 의미하고, ON UPDATE CASCADE는 키가 변경 불가능하지 않고 고유해야 함을 의미합니다.
Steven Huwig

6
더 좋은 점은 다음과 같습니다 SELECT name, address, amount FROM employees NATURAL JOIN payroll..
onedaywhen

5
스키마 추가의 경우 취약하기 때문에 배포 된 코드에서 자연스러운 조인을 사용하지 않습니다. 그러나 대화 형 쿼리의 경우 훌륭합니다.
Steven Huwig 2012

3
+1하지만 항상 예외가 있습니다. 예를 들어, 직원에 대한 외래 키인 급여에 두 개의 열이있는 경우 (예 : 지급되는 사람에 대한 참조, 두 번째는 예산 권한이있는 관리자에 대한 참조). 그러나 외래 키의 이름을 모두 지정할 수는 없습니다 employee_id.
빌 카윈

1
"using"키워드는 MySql에 따라 다릅니다. 안타깝게도 T-SQL에서는 작동하지 않습니다.
birdus

12

신청 방법에 따라 다릅니다. ORM을 사용하거나 테이블을 디자인하여 개체를 나타내는 경우 옵션 1이 적합 할 수 있습니다.

데이터베이스를 자체 레이어로 코딩하고 싶습니다. 나는 모든 것을 제어하고 앱은 저장 프로 시저 만 호출합니다. 특히 조인 된 테이블이 많고 많은 열이 반환되는 경우 완전한 열 이름을 가진 결과 집합을 갖는 것이 좋습니다. 이 유형의 응용 프로그램에서는 옵션 2를 좋아합니다. 조인에서 열 이름이 일치하는 것을보고 싶습니다. 나는 그들이 일치하지 않는 오래된 시스템에서 일했고 그것은 악몽이었습니다.


4
열 이름이 일치하지 않는 조인을 찾아야하는 경우 +1
Raj More

4
"오래된 시스템"에서 8 자 긴 이름의 핸디캡은 이것보다 훨씬 더 아프다. 나는 기꺼이 나가서 ID라는 PK를 갖는 것이 당신이 다루던 오래된 시스템에서 악몽의 주요 원인이 아니라고 추측합니다. 또한 "오래된 시스템에 빠졌다"는 소프트웨어 개발, 특히 데이터베이스에서 너무 자주 사용됩니다. 10 년 이상 전에 출시 된 DB 시스템에 대한 경험을 바탕으로 주어진 연습 A를 정당화하는 사람들을 일상적으로 봅니다.
Russell Steen

2
오늘날의 최첨단 응용 프로그램은 몇 년 안에 낡은 쓰레기 가 될 것 입니다. 인터페이스를 다시 작성하거나 다른 플랫폼에서 데이터를 사용할 수도 있지만 데이터 (열 이름 포함)는 시간의 테스트를 견뎌야합니다.
KM.

2
그렇다면 20 년 전의 사람들은 비록 8 자 밖에 없지만 오늘날 의미가있는 열 이름을 사용 했어야했을까요? 데이터 저장 형식은 지난 20 년 동안 크게 변경되었으며 향후 20 년 내에 다시 변경 될 것입니다. 귀하의 선호도가 나열된 다른 방법보다 시간의 시험을 더 잘 견딜 수 있다는 것을 입증 할 방법은 없습니다. "열 이름"은 데이터를 저장하고 조작하는 능력이 향상됨에 따라 사람들이 20 년 만에이 토론을 할 때 "오래된 쓰레기"일 수 있습니다. 테이블은 데이터 관계를 불완전하게 표현하는 인간 구조입니다 ...
Russell Steen

1
합리적인 지적 응답에 감사드립니다.
Russell Steen

3

두 규칙 모두 모든 경우에 작동하지 않는데, 왜 하나를 가지고 있습니까? 상식 사용 ...

예를 들어 자체 참조 테이블의 경우 동일한 테이블의 PK를 자체 참조하는 FK 열이 두 개 이상있는 경우 두 FK 열의 이름을 동일하게 지정할 수 없으므로 두 "표준"을 모두 위반해야합니다. , EmployeeId PK, SupervisorId FK, MentorId Fk, PartnerId FK, ...


1
실제 기술적 객관적 답변의 경우 +1
DVK

훌륭하고 적용 가능한 대답이지만 Dems의 대답에 대한 주장은 요점을 놓칩니다.
JYelton 2010

3

나는 그들 중 선택할 것이 거의 없다는 데 동의합니다. 나에게 어느 표준에 대해 훨씬 더 중요한 것은 "표준"부분입니다.

사람들이 '자신의 일을하기'시작한다면 그들은 네더에 의해 묶여 져야합니다. IMHO :)


3
일관성이 "올바른"것보다 더 중요하다는 것을 인식하는 +1 (이 경우)
Russell Steen

-1은 "어리석은 일관성"을 적용하려고합니다. 오래된 중국 속담은 "어리석은 일관성은 단순한 마음을위한 홉 고블린"이라고 말합니다.
Charles Bretana

@charles : 다른 사람들이 서로 코드를 유지하는 세상에서, 종종 작가가 떠났고 문서가 쓸모 없거나 존재하지 않을 때 이것은 어리석은 일관성이 아닙니다. 난 ... 당신과 함께 작동하지 않습니다 기뻐요
MatBailie

@Dems, 의도하지 않은 공격은 아니지만 이것은 두 가지 이유로 어리석은 일입니다. 1) 모든 표준을 위반해야하는 일반적이고 명확하게 이해되는 시나리오가 있습니다. 이 문제에 대한, 적어도, 표준은 매우 작은 값을 추가 할 수 있기 때문에 ... 기준이 더 편안한 느낌처럼 메이크업의 사람을 제외하고, (내 예에 대한 대답과 2 참조)
찰스 Bretana

1
"cars"테이블이나 "car"테이블에 영어 "carID"를 도입하자마자 "ID"가 더 일관성이 있다고 주장 할 수 있습니다. "sheep"테이블 또는 "sheeps"의 "sheepID"-일이 일관되지 않게됩니다. "ID"및 단일 테이블 이름을 고수하는 경우-이것은 일관성이있을뿐만 아니라 많은 ORM
훌륭하게

3

다음을 고려해 보셨습니까?

Primary Table (Employee)   
Primary Key is PK_Employee

Foreign table (Event)  
Foreign key is called FK_Employee

3
사람들이 투표를 거부 할 때 참을 수없고 이유를 밝히지 않습니다. 이것은 완전히 타당한 대답입니다. 일부 사람들에게 입맛에 맞는지 여부는 다른 질문이지만 주관적이며 반대표가 필요하지 않습니다.
Jeremy

1
지적 해 주셔서 감사합니다. 이 형식을 사용 하지 않는 이유에 대해서도 관심 이 있습니다. 그리고 나는 확신 ... 좋은 이유가있을 것입니다 해요
WOUTER

이것은 table_name.column_name쿼리에서 사용할 필요가없고 반복되는 이름이없는 경우 열 이름에 별칭을 사용할 필요가 없기 때문에 가장 좋은 방법입니다 ...
Please_Dont_Bully_Me_SO_Lords

1
이것은 헝가리 표기법의 한 형태로 간주 될 수 있습니다. 따라서 찬성 및 반대 주장을 고려하십시오.
Fred

2

내가 일하는 곳에서 사용하는 규칙은 A와 매우 비슷하지만, 복수형 (즉, "employees")으로 테이블 이름을 지정하고 테이블과 열 이름 사이에 밑줄을 사용한다는 점만 제외하면됩니다. 이것의 장점은 열을 참조 할 때 액세스하려는 방법에 따라 "employees _ id"또는 "employees.id"라는 것입니다. 열이 나오는 테이블을 지정해야하는 경우 "employees.employees _ id"는 확실히 중복됩니다.


복수형 테이블 이름을 좋아하는지 결정하지 않았습니다. 단수를 사용하면 쿼리가 더 잘 읽는 것처럼 보입니다 ( "employees.name"이 아닌 "employee.name"). 조인에서도 단일 레코드를 다른 테이블에 조인하면 더 잘 읽는 것 같습니다. 그러나 복수형 테이블 이름은 쿼리보다 테이블에 대해 생각할 때 더 정확 해 보입니다. 나는 우리가 무엇을 사용으로 단수 고수있을거야,하지만 난 (많은 사람들이 동의하지만 다시) 그것은 또한 갈 수있는 올바른 방법이라고 생각
MatBailie

네. 그것은 개인적인 선호도 및 / 또는 당신이 보았던 것에 익숙한 것입니다.
Jarett Millard

2

데이터베이스 쿼리뿐만 아니라 응용 프로그램 코드를보고 있다면 다음과 같은 사항이 분명해 보입니다.

  1. 테이블 정의는 일반적으로 하나의 객체를 설명하는 클래스에 직접 매핑되므로 단수 여야합니다. 객체의 컬렉션을 설명하기 위해 저는 일반적으로 단수 이름에 "Array", "List"또는 "Collection"을 추가합니다. 이는 복수형을 사용하는 것보다 더 명확하게 그것이 컬렉션이라는 것을 의미 할뿐만 아니라 어떤 종류의 컬렉션인지를 나타냅니다. 그것은. 이보기에서 테이블 이름은 컬렉션의 이름이 아니라 컬렉션이 속한 개체 유형의 이름으로 표시됩니다. 애플리케이션 코드를 작성하지 않는 DBA는이 점을 놓칠 수 있습니다.

  2. 내가 다루는 데이터는 종종 키가 아닌 식별 목적으로 "ID"를 사용합니다. 키 "ID"와 키가 아닌 "ID"간의 혼동을 없애기 위해 기본 키 이름에 대해 테이블 ​​이름이나 약어가 접두사로 붙은 "키"(그렇지 않습니까?)를 사용합니다. 테이블 이름. 이 접두사 (그리고 저는 이것을 기본 키에 대해서만 예약합니다)는 키 이름을 고유하게 만듭니다. 이는 데이터베이스 열 이름과 동일한 변수 이름을 사용하고 대부분의 클래스에는 다음 이름으로 식별되는 부모가 있기 때문에 특히 중요합니다. 부모 키. 이것은 또한 "Key"만있는 예약 된 키워드가 아닌지 확인하는 데 필요합니다. 키 변수 이름의 일관성을 유지하고 자연스러운 조인을 수행하는 프로그램을 제공하기 위해 외래 키는 기본 키인 테이블에 사용 된 것과 동일한 이름을 갖습니다. 자연 조인을 사용하여 이런 방식으로 훨씬 잘 작동하는 프로그램을 한 번 이상 접했습니다. 이 마지막 지점에서 내가 사용한 자체 참조 테이블에 문제가 있음을 인정합니다. 이 경우 외래 키 명명 규칙에 예외를 적용합니다. 예를 들어, Employee 테이블에서 ManagerKey를 외래 키로 사용하여 해당 테이블의 다른 레코드를 가리 킵니다.


Entity Framework와 같은 많은 개체 관계형 매퍼 (ORM)를 사용하면 테이블을 다른 이름의 클래스에 매핑 할 수 있습니다. 이를 통해 "User"라는 클래스와 "Users"라는 테이블을 가질 수 있습니다.
Fred

2

나는 컨벤션 # 2를 좋아합니다.이 주제를 조사하고 내 질문을 게시하기 전에이 질문을 찾는 과정에서 다음과 같은 문제가 발생했습니다.

많은 수의 열이있는 테이블에서 *를 선택하고 비슷하게 많은 수의 열이있는 두 번째 테이블에 결합합니다. 두 테이블 모두 기본 키로 "id"열이 있으며 이는 결과에서이 두 값을 고유하게 만들기 위해 모든 열 (내가 아는 한)을 구체적으로 선택해야 함을 의미합니다.

SELECT table1.id AS parent_id, table2.id AS child_id

난 여전히 같은 이름을 가진 결과의 일부 열이있을 것이다 컨벤션 # 2 수단을 사용하지만, 지금은 지정할 수 있는 스티븐 Huwig는 제안으로, 아이디 I 필요 (부모 또는 자녀)과 USING더 문 단순화 것을.


2
SELECT *어쨌든 (대부분의) 프로덕션 쿼리에는 아니오이므로 명명 표준을 선택할 이유가별로 없습니다.
P Daddy

1
동의하지 않음 : 그 이유에 대한 링크를 제공 할 수 있습니까? 내 쿼리에서 80 개의 열 이름을 유지해야한다는 생각이 마음에 들지 않습니다.
JYelton 2010

현재 링크를 찾을 수 없습니다 ( "*"로 Google 검색이 어렵습니다). 기본 사항을 간략히 설명하겠습니다. (1) 테이블 변경은 애플리케이션에 부정적인 영향을 미칠 수 있습니다. (2) 성능에 좋지 않으며 (3) 실제로 필요한 데이터를 명시 적으로 지정하면 코드를 더 쉽게 이해할 수 있습니다. 이러한 점은 확장 될 수 있으며 예외가 있습니다 (제가 언급했듯이). 여기에서는 적절하지 않습니다. 이 질문을 새 질문으로 게시하면 나 (및 다른 사람들)가 더 자세히 설명해 드리겠습니다.
P Daddy

2
그렇게 할 수 있습니다. 성능상의 이점을 알고 있지만 코드를 편집 할 때 시간 투자를 고려해야합니다. 저는 항상 앱과 데이터베이스 간의 상호 작용을 개선 할 방법을 찾고 있습니다. 감사.
JYelton 2010

1
나는 SELECT *대부분의 프로덕션 쿼리에 대해 아니오라고 확신하지 않습니다 . 개발 속도를 크게 높이고 코드를 훨씬 간결하고 읽기 쉽게 만들어 더 중요한 문제에 집중할 수 SELECT *있다면 어떨까요? 이는 각 상황의 상황에 따라 크게 달라지며 여러 요인 간의 균형입니다. 하나의 규칙이 모든 것에 거의 맞지 않습니다.
niico

2

난 항상 사용했던 사용자 ID 하나의 테이블에 PK로 userId를 FK 같은 다른 테이블에. userIdPKuserIdFK 를 이름으로 사용하여 서로 를 식별 하는 것에 대해 진지하게 생각하고 있습니다. 테이블을 볼 때 PK와 FK를 빠르게 식별하는 데 도움이 될 것이며 PHP / SQL을 사용하여 데이터에 액세스 할 때 코드를 정리하여 이해하기 쉽게하는 것 같습니다. 특히 다른 사람이 내 코드를 볼 때.


1

나는 규칙 # 2를 사용합니다. 주어진 테이블에서 의미하는 바를 모르는 레거시 데이터 모델로 작업하고 있습니다. 장황함에 대한 해악은 어디에 있습니까?


1

외래 키 이름을 지정하는 방법

role_id

여기서 role은 참조 된 엔티티가 현재 테이블에 상대적인 역할입니다. 이것은 동일한 테이블에 대한 재귀 참조 및 다중 fks 문제를 해결합니다.

대부분의 경우 참조 된 테이블 이름과 동일합니다. 이 경우 제안 중 하나와 동일하게됩니다.

어쨌든 긴 논쟁을하는 것은 나쁜 생각이다


0

""employee INNER JOIN order ON order.employee_id = employee.id "어디에 추가 자격이 필요합니까?"

내가 말한 자격이 이미 있기 때문에 추가 자격이 필요하지 않습니다.

"비즈니스 사용자가 주문 ID 또는 직원 ID를 참조하는 이유는 컨텍스트를 제공하기위한 것이지만 데이터베이스 수준에서는 테이블을 참조하기 때문에 이미 컨텍스트가 있습니다."

열이 'ID'로 명명 된 경우 내가 말한 방식대로 ID 열에 대한이 참조를 정확하게 규정하지 않는 한 "표에 대한 [원문] 참조"가 정확히 어떻게 수행됩니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.