사람들이 ID 열에 'Id'라는 이름을 사용하지 않는 것이 좋은 이유는 무엇입니까?


68

나는 Id테이블의 ID 열에 이름을 사용하지 말라고 배웠지 만 요즘에는 데이터가 실제로 무엇인지에 대해 간단하고 짧으며 매우 설명하기 때문에 어쨌든 그것을 사용하고 있습니다.

사람들 Id이 테이블 이름으로 접두사 를 제안하는 것을 보았지만 특히 SQL 쿼리 (또는 Entity Framework와 같은 ORM을 사용하는 경우 프로그래머)를 작성하는 사람, 특히 다음과 같은 긴 테이블 이름에서 더 많은 작업을 수행하는 것처럼 보입니다. CustomerProductId또는AgencyGroupAssignementId

우리를 위해 무언가를 만들기 위해 고용 한 한 타사 공급 업체는 실제로 Ident사용하지 않기 위해 모든 ID 열의 이름을 지정했습니다 Id. 처음 Id에는 키워드 때문이라고 생각 했지만 키워드를 살펴보면 IdSQL Server 2005의 키워드가 아니라는 것을 알았습니다 .

그렇다면 왜 사람들 Id은 ID 열에 이름 을 사용하지 않는 것이 좋습니다 ?

편집 : 명확히하기 위해 어떤 명명 규칙을 사용할 것인지 또는 다른 명명 규칙을 사용하는 인수에 대해 묻지 않습니다. IdID 열 이름에 사용하지 않는 것이 좋은 이유를 알고 싶습니다 .

저는 dba가 아닌 단일 프로그래머이며 데이터베이스는 데이터를 저장하는 장소입니다. 일반적으로 작은 앱을 빌드하고 일반적으로 데이터 액세스에 ORM을 사용하기 때문에 ID 필드의 공통 필드 이름을 사용하는 것이 훨씬 쉽습니다. 이 작업을 수행하여 누락 된 내용을 알고 싶습니다.이를 수행하지 않는 것이 좋은 이유가 있다면.


10
BF bunfight는 이미 여기에있다 : programmers.stackexchange.com/q/114728/5905 우리 중 몇몇은 (나를 읽었다) 그것에 빠졌다 .
gbn

ID 열의 이름으로 "id"를 사용하는 것에 대한 규칙이 실제로 있습니까? Ruby on Rails의 표준 ORM 인 ActiveRecord는 규칙에 따라 정확하게 수행합니다. ar.rubyonrails.org
200_success

1
@ 200_success 데이터베이스 수준에서 그렇습니다. 이것은 ORM 사이트가 아니라 데이터베이스 사이트입니다.)
JNK

2
또한 SQL Server에 대한 자세한 내용은 dba.stackexchange.com/questions/124655/… 및보다 구체적으로 connect.microsoft.com/SQLServer/feedback/details/2178150
Aaron Bertrand를

답변:


46

테이블 이름 접두사는 매우 좋은 이유가 있습니다.

치다:

TableA (id int identity, stringdata varchar(max))

TableB (id int identity, stringdata varchar(max))

두 테이블 모두에 존재 DELETE하는 TableA레코드를 원합니다 . 충분히 쉽게, 우리는 단지 INNER JOIN:

DELETE a
FROM 
  TableA A
INNER JOIN 
  TableB B
    ON b.id = B.id

.... 그리고 우리는 방금 모두 지 웠습니다 TableA. 우연히 B의 ID를 자체와 비교했습니다. 모든 레코드가 일치하고 모든 레코드가 삭제되었습니다.

필드의 이름이 지정 TableAId되었고 TableBId이것이 불가능한 경우 ( Invalid field name TableAid in TableB).

개인적으로 나는 id테이블 에서 이름을 사용하는 데 아무런 문제가 없지만 실수로 잘못된 필드와 비교하고 불고 피하는 것을 피하기 위해 테이블 이름 (또는 엔티티 이름, TableA사람들 PeopleId이 잘 작동 한다면 엔티티 이름)을 사용하는 것이 좋습니다 뭔가.

이것은 또한 많은 쿼리를 가진 긴 쿼리에서 필드가 어디에서 오는지를 매우 분명하게 만듭니다 JOIN.


10
기본적으로 오류를 방지하기위한 명명 규칙입니까? 나는 더 모호한 이름 지정 체계를 사용하는 것보다 imo를 사용 begin transaction하고 생각하는 commit transaction것이 좋습니다.
Rachel

13
@Rachel : 1. 명확성입니다. 2. 불필요한 열 별명을 피하십시오 3. JOIN..USING을 허용하십시오. 4. 단일 객체에서 작업하는 PHP 원숭이를 성가 시게하지 마십시오
gbn

4
@Rachel 쿼리를 작성할 때 실수를 발견하지 않고 실행 직전에 쿼리를 수행하기 전에 실수를 발견하지 못할 수도 있습니다. 이런 일이 발생하는 이유는 무엇입니까?
Andy

7
@Andy는 항상을 SELECT실행하기 전에 내 레코드를 찾기 위해 a 를 수행 DELETE하고 일단 명령문을 실행하면 항상 행 수가 커밋하기 전에 예상 한 것임을 확인합니다.
Rachel

5
@Rachel 그것은 당신에게 당신을 위해 일하는 것이 좋은 점입니다. 모든 사람이 그렇게 할 수 있습니까?
Andy

36

대부분 외래 키가 엄청난 고통을 겪지 않도록하는 것입니다. Customer와 CustomerAddress라는 두 개의 테이블이 있다고 가정합니다. 둘 다의 기본 키는 ID (int) 열인 id라는 열입니다.

이제 CustomerAddress에서 고객 ID를 참조해야합니다. 열 ID의 이름을 지정할 수 없으므로 customer_id로 이동하십시오.

이로 인해 몇 가지 문제가 발생합니다. 먼저, "id"열을 호출 할시기와 "customer_id"를 호출 할시기를 일관되게 기억해야합니다. 그리고 이것을 엉망으로 만들면 두 번째 문제가 발생합니다. 십여 개의 조인으로 큰 쿼리를 받았는데 데이터가 반환되지 않으면 Waldo의 위치를 ​​연주 하고이 오타를 사냥하는 것이 재미 있습니다.

ON c.id = ca.id

그렇습니다 ON c.id = ca.customer_id. 또는 더 나은 방법으로 식별 열의 이름을 설명 적으로 지정하면 ON c.customer_id = ca.customer_id됩니다. 그런 다음 실수로 어딘가에 잘못된 테이블 별칭을 사용하면 customer_id는 해당 테이블의 열이 아니므로 빈 결과와 후속 코드 흠집이 아닌 멋진 컴파일 오류가 발생합니다.

물론, 한 테이블에서 다른 단일 테이블로 여러 외래 키 관계가 필요하지만 모든 기본 키 이름을 "id"로 지정해도 도움이되지 않는 경우와 같이 이것이 도움이되지 않는 경우가 있습니다.


27

다음은 모든 기본 키에 공통 이름을 사용하지 않는 컨벤션에서 얻은 이점에 대한 모든 답변을 요약 한 것입니다.

  • 아이디 필드의 이름이 같지 않기 때문에 실수가 줄어 듭니다.

    아이디 필드의 이름이 정확히 동일하지 않으므로 B.Id = B.Id대신 대신 조인하는 쿼리를 실수로 작성할 수 없습니다 A.Id = B.Id.

  • 더 명확한 열 이름.

    라는 열을 보면 CustomerId해당 열에 어떤 데이터가 있는지 즉시 알 수 있습니다. 열 이름이 일반적인 Id이름 인 경우 열에 포함 된 데이터를 알고 있어야하며 테이블 이름을 알아야합니다.

  • 불필요한 열 별명을 피하십시오

    이제 쓸 수 있습니다 SELECT CustomerId, ProductId조인 쿼리에서 Customers함께 Products대신,SELECT Customer.Id as CustomerId, Products.Id as ProductId

  • JOIN..USING구문을 허용 합니다

    Customer JOIN Products USING (CustomerId)대신 구문으로 테이블을 조인 할 수 있습니다.Customer JOIN Products ON Customer.Id = Products.Id

  • 검색에서 키를 쉽게 찾을 수 있습니다

    대규모 솔루션에서 고객의 ID 필드를 찾고 있다면 검색하는 CustomerId것이 검색하는 것보다 훨씬 유용합니다.Id

이 명명 규칙이 갖는 다른 장점을 생각할 수 있으면 알려 주시면 목록에 추가하겠습니다.

ID 필드에 고유하거나 동일한 열 이름을 사용하기로 선택했는지 여부는 귀하에게 달려 있지만 선택한 내용에 관계없이 일관성을 유지하십시오.)


12

링크 된 질문에서 내 답변을 복사하려면 :

모든 테이블에서 "ID"를 사용하는 것이 최선의 아이디어가 아닌 상황이 있습니다 ( USING키워드가 지원되는 경우). 우리는 MySQL에서 자주 사용합니다.

예를 들어 fooTablecolumn fooTableIdbarTableforeign key가 fooTableId있으면 쿼리를 다음과 같이 구성 할 수 있습니다.

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

그것은 타이핑을 절약 할뿐만 아니라 대안에 비해 훨씬 더 읽기 쉽다 :

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)

9

중복성을 제한하기 위해 데이터베이스 스키마를 정규화 한 후, 테이블은 설정된 관계 (일대일, 일대 다, 다 대다)로 더 작은 테이블로 나뉩니다. 프로세스에서 원래 테이블의 단일 필드가 여러 정규화 된 테이블에 나타날 수 있습니다.

예를 들어, Author_Nickname에 대한 고유 제한 조건을 가정하여 블로그 데이터베이스가 정규화되지 않은 형식으로 표시 될 수 있습니다.

| Author_Nickname | Author_Email | Post_Title | Post_Body |
+-----------------+--------------+------------+-----------+
| dave            | dave@x.com   | Blah       | Bla bla   |
| dave            | dave@x.com   | Stuff      | I like    |
| sophie          | s@oph.ie     | Lorem      | Ipsum     |

정규화하면 두 개의 테이블이 생성됩니다.

저자:

| Author_Nickname | Author_Email |
+-----------------+--------------+
| dave            | dave@x.com   |
| sophie          | s@oph.ie     |

우편

| Author_Nickname | Post_Title | Post_Body |
+-----------------+------------+-----------+
| dave            | Blah       | Bla bla   |
| dave            | Stuff      | I like    |
| sophie          | Lorem      | Ipsum     |

여기서 Author_Nickname은 author 테이블의 기본 키이고 post 테이블의 외래 키입니다. Author_Nickname이 두 테이블에 표시 되더라도 여전히 단일 정보 단위에 해당합니다. 각 열 이름은 단일 필드에 해당합니다 .

대부분의 경우 원래 필드에는 고유 제한 조건이 없으므로 숫자 인공 필드가 기본 키로 대신 사용됩니다. 각 열 이름이 여전히 단일 필드를 나타내는 사실은 변경되지 않습니다. 기존 데이터베이스 설계에서 개별 열 이름은 키가 아니더라도 단일 필드에 해당합니다. (예를 들어, part.nameclient.name 대신 part.partnameclient.clientname을 사용합니다 ). 이것이 와 구문 이 존재하는 이유입니다 .INNER JOIN ... USING <key>NATURAL JOIN

그러나 오늘날 많은 언어로 ORM 계층을 쉽게 사용할 수있는 데이터베이스는 종종 OO 언어의 지속성 계층으로 설계되며, 다른 클래스에서 동일한 역할을 갖는 변수를 동일한 ( part.nameclient.name , part.partnameclient.clientname 아님). 그러한 맥락에서, 나는 기본 키에 'ID'를 사용하는 경향이 있습니다.


7

우리를 위해 무언가를 만들기 위해 고용 한 타사 공급 업체 중 하나는 실제로 ID를 사용하지 않기 위해 모든 ID 열을 Ident로 명명했습니다.

"Id"대신 "Ident"를 사용한다고해서 "Ident"가 모든 테이블에서 사용되는 경우 실제로 해결되지 않습니다.

Drupal 사이트의 SQL 코딩 규칙에 대한 좋은 기사가 있습니다.

네임 스페이스 충돌을 방지하기 위해 테이블 ​​이름 앞에 모듈 이름을 접두어로 사용하는 것이 좋습니다.

이러한 관점에서 CustomerProductId 및 AgencyGroupAssignmentId는 사용하는 것이 좋습니다. 예, 매우 장황합니다. 당신은 그것을 줄일 수 있지만, 가장 큰 관심사는 당신을 따르는 개발자가 당신이 무엇을 의미하는지 이해할지 여부 입니다. 자세한 테이블 이름이있는 ID는 무엇인지 모호하지 않아야합니다. 그리고 (나에게) 몇 번의 키 입력을 저장하는 것보다 더 중요합니다.


7

ID 대신 열의 이름을 CustomerID로 지정합니다.

FROM dbo.Customers AS c JOIN dbo.CustomerOrders AS o

SQL 프롬프트는 즉시 다음을 제안합니다.

ON c.CustomerID = o.CustomerID 

그것은 몇 가지 키 입력을 저장합니다. 그러나 나는 이름 지정 규칙이 매우 주관적이라고 생각하며 어떤 식 으로든 강한 의견을 가지고 있지 않습니다.


5

모든 varchar 필드 이름을 "UserText"및 "UserText1"과 같은 이름으로 지정하지 않거나 "UserDate"및 "UserDate1"을 사용하지 않는 이유도 마찬가지입니다.

일반적으로 테이블에 ID 필드가 있으면 기본 키입니다. 두 테이블의 기본 키가 모두 ID 인 경우 상위 테이블에 대한 외래 키를 사용하여 자식 테이블을 어떻게 구축합니까?

모든 사람 이이 방법에 동의하지는 않지만 내 데이터베이스에서 각 테이블에 고유 한 약어를 지정합니다. 해당 테이블의 PK 이름은 PK_ [abbrv] ID입니다. FK로 사용되는 경우 FK_ [abbrv] ID를 사용합니다. 이제 테이블 관계가 무엇인지 알아내는 데 전혀 추측이 없습니다.


5

기본적으로 같은 이유로 매개 변수의 이름을 parameter1, parameter2로 지정하지는 않습니다. 정확하지만 설명이 아닙니다. TableId가 표시되면 컨텍스트에 관계없이 Table에 대한 pk를 보유하는 데 사용된다고 가정 할 수 있습니다.

Ident를 사용하는 사람은 Ident와 Id 사용 ID 중 하나를 선택하면 요점을 완전히 놓칩니다. ID는 Id보다 훨씬 혼란 스럽습니다.

맥락에서 볼 때 Id는 일부 테이블의 기본 키로 간주 될 수 있지만 (id가 guid가 아닌 한 매우 유용하지는 않지만) Ident는 심지어 당신에게 (또는 적어도 나에게) 말하지 않습니다. 나는 결국 아이덴티티가 신원을 나타내는 데는 짧은 길이라는 것을 알아낼 것이지만, 그것을 알아내는 데 소비 한 시간은 낭비 될 것입니다.


3

natural join/ 키를 수행 할 수 있도록 기본 키와 외래 키 컨텍스트 모두에서 동일한 이름을 사용할 수 있도록 접두사를 사용하십시오 join ... using.

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