데이터베이스에서 열에 레이블을 지정하는 효과적인 방법은 무엇입니까?


30

데이터베이스의 열에 다음과 같이 레이블을 지정했습니다.

user_id
user_name
user_password_hash

두 테이블을 조인 할 때 충돌을 피하기 위해 테이블 ​​별칭을 지정하는 방법에 대해 더 많이 배웠습니다.

데이터베이스에서 열에 레이블을 지정하는 효과적인 방법은 무엇입니까? 왜?


어떤 데이터베이스? Oracle에서 레이블을 지정하는 방법은 이름이 일치하는 경우 기준 조인 할 열을 자동으로 선택하는 기능으로 인해 대부분의 다른 데이터베이스와 다릅니다.
Joe

@Joe, 저는 항상 MySQL과 SQLite3을 사용했지만 대부분의 다른 데이터베이스에 적용해야합니다.
Thomas O

@joe는 오라클이 다르다는 것을 결코 알지 못했습니다. 당신은 링크를 줄 수 있습니까?
bernd_k

@bernd_k : 아래 에 내 답변에 링크를 추가했습니다
Joe

답변:


33

귀하의 경우 접두사 사용자는 중복입니다. 우리 (담당자)는 이것이 테이블 사용자라는 것을 알고 있으므로 왜 user_모든 필드 앞에 접두사를 추가 합니까?

내가 당신에게 제안하는 것은보다 자연스러운 접근 방식으로하는 것입니다.

사람의 특성은 무엇입니까 : 성, 이름, 생년월일, 국적 등.

자동차의 특성은 무엇입니까 : 모델, 연도, 색상, 에너지 등

당신의 칼럼은 가능한 한 자연 스러워야합니다. 그것은 당신과 당신을 따르는 모든 사람들에게 스키마를 더 명확하게 만들 것입니다. 이것을 유지 보수 단계라고도하며 유지 관리를보다 쉽게하기 위해 수행 할 수있는 모든 것이 일반적으로 노력할 가치가 있습니다.


1
그렇습니다. 사람들이 그렇게하면 나에게 화를냅니다. 또한 모든 테이블 tbl_whatever를 호출 할 때도 사용됩니다.
Gaius

이것은 또한 "클래스 단어"의 개념과 관련이 있으며, 클래스 단어가 적절하고 적합하지 않은 경우 커뮤니티에서 약간의 논쟁이있는 것 같습니다. (클래스 단어는 다음과 같은 도구입니다. 데이터의 고유 한 범주 또는 분류를 식별하고, 데이터 이름으로 설명되는 데이터 유형을 설명하고, 데이터 요소와 관련된 데이터의 주요 분류를 설명하십시오.)
Jon Schoning

17

Spredzy의 의견 외에도 기본 키에 동일한 (ID) 레이블을 지정하여 즉시 쿼리를 작성할 때 "국가 ID를 검색하지 않고 쉽게 (u.ID = c.ID)를 검색 할 수 있습니다. , country_ID, countries_ID, countriesID,? "


5
한때 DBA가 일부 테이블에서 ID를 사용하고 다른 테이블에서 ID를 사용하기로 결정한 데이터베이스에서 작업했으며 MySQL은 대소 문자를 구분하도록 설정했습니다. 재미있는 시간!
Toby

6
우리는 일반적으로 tablename.tablename_id를 사용합니다. 예 : car.car_id; person.person_id. 테이블의 단수 이름.
glasnt

@glasnt 똑똑한 결정.
garik

1
이것은 실제로 매우 나쁜 생각이며 SQL USING절 을 사용하는 기능을 잃게됩니다 (사양에 위배됩니다).
Evan Carroll

9

Spredzy의 훌륭한 답변에 대한 David Hall의 부록에 대해서는 더 동의 할 수 없었습니다. 간단하고 자연스럽게가는 길입니다. 테이블 이름을 자연스럽게 지정하면 테이블 혼동이 문제가되지 않습니다.

users.id 및 cars.id를 가질 수있을 때 users.user_id 및 cars.car_id를 갖는 것은 의미가 없습니다.


7

데이터베이스 스키마에서 모든 열은 테이블에서 고유 한 이름을 가져야한다고 주장합니다. 몇 가지 이유가 있습니다.

  • 모델링 관점에서 : 수프 속성으로 시작하여 테이블로 정규화합니다. 시간이 지남에 따라 비정규 화 또는 정규화 또는 추가 뷰 또는 구체화 된 뷰를 도입하거나 새 테이블을 도입 할 수 있습니다. 모든 열 이름이 고유 한 경우 문제가되지 않습니다.

  • 이 조인 구문을 사용할 수 있습니다 : a JOIN b USING (a_id) JOIN c USING (a_id). 매우 편리하며 다음 사항을 도와줍니다.

  • 조인이 많은 쿼리를 실행하거나을 사용하여 구체화 된 뷰를 만들면 SELECT *충돌이 발생하지 않습니다. 가입 생각해 person.name, product.name, country.name, 등 Urgh.

  • 일반적으로 쿼리가 크면 id어디에서나 의미 가 무엇인지 추적하기가 어렵습니다 .


직원 이름과 사이트 이름의 열 이름을 어떻게 지정 하시겠습니까? 이름 레이블 열의 중복성을 어떻게 피할 수 있습니까?
Spredzy

@ Spring : 중복과 함께 갈 것입니다.
피터 아이젠 트라우트

1
이러한 우려에 대한 답변 : 별칭.
모든 거래의 존

7

예를 들어 다음과 같이 보일 것입니다.

USERS
----
id
username,
password
registration_date

테이블 이름을 대문자로 사용합니다. 이를 통해 테이블을 쉽게 식별 할 수 있습니다. 방금 이름을 지정한 열은 각각이 나타내는 것입니다. 숫자를 사용하지 않거나 접두사 또는 접미사를 포함시키지 마십시오. 이렇게하면 쿼리가 간단하고 간단 해집니다.

BTW, 나는 당신이 좋아하는 스타일을 찾아서 고수해야한다고 생각합니다. 자주 변경하면 더 복잡한 DB 스키마가 생깁니다.


"좋아하는 스타일을 찾아서 고수하세요"+1 일관성은 특정 표준을 정확하게 준수하는 것보다 낫습니다 (아직 표준을 선택하지 않은 경우 일부는 다른 표준보다 낫습니다).
모든 거래의 존

5

다른 것과 마찬가지로 테이블 이름을 열의 일부로 포함하지 않는 것이 좋습니다. 열 이름이 대부분 비슷한 수백 개의 테이블이없는 한 : ID라는 열이있는 수십 개의 테이블이 모두 있으면 테이블 이름 앞에 접두사를 붙입니다.

최근에 개발자 중 한 명이 기본 키 및 외래 키 열 앞에 pk 및 fk를 붙이는 것을 선호하는 회사를 떠났습니다. 이로 인해 열이 pkfk (일반적으로 2 개의 열을 기반으로하는 복합 기본 키 중 하나는 다른 테이블의 외래 키임)로 시작되는 일부 가증이 발생합니다.


4
fk_cluster로 간주됩니까?
Kaji

5

각 열 이름이 테이블 이름에서 파생 된 접두어로 시작하는 환경에서 일하고 있는데 내 발명은 아니지만 매우 만족합니다.

이상적으로 열 이름은 데이터베이스의 모든 테이블에서 고유합니다.

일부 관찰 :

  • 테이블이 select 문에서 여러 번 조인 될 때 ​​테이블 별칭 만 필요합니다.
  • 열 이름을 테이블 이름에 맞게 조정해야하기 때문에 코드 스 니펫을 복사 할 때 일부 결함을 방지합니다.
  • 외래 키 열이 가리키는 테이블을 표시하는 데 도움이됩니다.

일반적인 아이디어 : 가장 중요한 것은 각 명명 규칙의 일관성입니다.-단수와 복수 (열은 아닌 테이블에 적용됨)-기본 및 외래 키 식별 (데이터베이스의 내용과 구조를 구축)-일관성이있을 때 같은 문자열의 문자열과 짧은 변형을 저장합니다-플래그, 상태 등과 일치해야합니다.


3

Spredzy의 답변에 동의하지만 선호 사항에 따라 under_score 대신 camelCase를 사용한다고 덧붙입니다.

성, 성 등


2
CamelCase가 모든 데이터베이스 시스템에서 작동하지 않고 데이터베이스 시스템을 지정하지 않았기 때문에 -1입니다. 예를 들어, Oracle에서 CamelCase를 사용하는 것은 나쁜 소식입니다. (작은 따옴표를 사용하여 작성해야하지만 그 이후에는 액세스하는 모든 사용자가 후프를 뛰어 넘어 액세스 / 사용해야합니다). 악몽이야
ScottCher

@ScottCher-Oracle에서 작동하지 않는다는 것을 알지 못했지만 Oracle DBA는 아닙니다. 열 이름이 문제의 DBS가 설정 한 규칙을 먼저 준수해야한다고 생각했을 것입니다.
Toby

3

Oracle의 경우 열 이름을 'id'또는 'name'또는 일반적인 이름으로 지정 하지 않을 수 있습니다.

문제는 기본적 으로 이전 버전 에서는 Oracle이 유사한 열 이름을 기반으로 테이블을 조인하려고 시도하므로 모든 이름을 올바르게 지정하면 테이블 사이에 기본 조인 절을 지정하게됩니다.

그러나 Oracle을 사용 하지 않더라도 여러 테이블에 표시되는 이름을 선택하지 않으면 두 테이블 중에서 선택해야 할 때마다 앨리어싱 문제를 겪지 않아도됩니다.

SELECT
  instrument.name as instrument_name,
  instrument.abbr as instrument_abbr,
  source.name     as source_name,
  source.abbr     as source_abbr,
  ...
FROM ...

따라서 다중 테이블 선택이 표준 인 경우 열 이름이 길수록 입력 내용이 저장됩니다. (한 번에 하나의 테이블 만 사용하는 경우 ... 관계형 데이터베이스가 정말로 필요합니까?)

... 그리고 타이핑을 저장하면 Oracle에서 또 다른 문제가 발생합니다. 적어도 8i (Oracle SQL Tuning 및 Data Modeling 코스를 수강 한 현재 버전)에서 실행 계획의 캐싱은 쿼리 (정확한 값을 기억할 수 없습니다 ... 1024?) where 절 끝 부분에서 무언가 다른 쿼리와 추출하는 열 목록이 길면 쿼리가있는 경우 실행 계획을 올바르게 캐시 할 수 없으므로 성능이 저하 될 수 있습니다.

오라클은 좋은 테이블 및 열 이름이라고 주장하는 것을 선택하는 데 대한 가이드를 가지고 있었는데, 기본적으로 약 5-8 자까지 문자를 제거하기위한 가이드이지만 그다지 신경 쓰지 않았습니다.

...

그 이외의 일이 진행되면서 :

  • 열은 항상 단수입니다 (테이블은 항상 복수 임)
  • 대소 문자 구분이있는 경우를 대비하여 모든 이름은 소문자입니다.
  • 위의 결과로 낙타 케이스 대신 밑줄을 사용하십시오.

업데이트 : Oracle의 조인 동작에 익숙하지 않은 사용자는 Mastering Oracle SQL : Join Conditions 에 대한 마지막 예제를 참조하십시오 .

어떻게 된 거예요? 그 이유는 supplier_id를 제외하고이 두 테이블에 공통 이름을 가진 다른 열 쌍이 있기 때문입니다. 그 열은 이름입니다. 따라서 공급 업체와 부품 테이블간에 자연스럽게 조인을 요청하면 두 테이블의 supplier_id 열을 동일하게함으로써뿐만 아니라 두 테이블의 이름 열도 동일하게 조인됩니다. 동일한 공급 업체의 부품 이름과 동일한 공급 업체 이름이 없으므로 쿼리에서 행을 반환하지 않습니다.

'이전 조인 구문'(8i 및 이전)에서 'NATURAL JOIN'이 기본 조인 동작이며 조인 조건을 지정하지 않은 경우에도 여전히 그렇습니다. 일단 'NATURAL JOIN'이 9i의 공식 옵션이 되었으면 일반적인 권장 사항은 사용하지 않는 것입니다. 열 이름이 잘못되면 문제가 생길 수 있기 때문에 좋은 열 이름을 옹호합니다.


4
두 번째 단락에서 "내츄럴 조인"을 언급하고 있습니까? 그렇다면 SHUDDER ... 가능할 때마다 데이터베이스 시스템이 테이블을 결합하는 방법을 지정해야합니다. 데이터베이스에 맡겨 결정하면 예기치 않은 / 일관되지 않은 결과가 발생할 수 있습니다. 또한 자연 조인은 두 테이블 간의 조인으로 제한되므로 사용 편의성이 상대적으로 제한됩니다.
ScottCher

2
NATURAL JOIN은 기본값이 아닙니다. 명시 적 조인이 제공되지 않으면 직교 조인이 수행됩니다 (예 : 테이블의 각 행이 다른 테이블의 각 행에 조인 됨). ANSI 조인이 지원되기 전에 (즉, FROM 절에 지정된 조인) WHERE 절에서 조인을 수행해야했습니다.
Gary

1
자연 조인의 경우 -1입니다. 관련이없는 스키마 변경으로 인해 조인이 끊어 지거나 오류가 발생하더라도 오류가 발생하지 않으면 변경 될 수 있습니다. 자녀를 생각하고 항상 조인 필드를 지정하십시오.
모든 거래의 존

2
@ScottCher : "결정하기 위해 데이터베이스에 맡기십시오"-먼저 아마도 "데이터베이스"가 아닌 "DBMS"를 의미합니다. 둘째, Oracle에는 AI 또는 의인화 메커니즘이 없습니다. 오히려 NATURAL JOIN결정적입니다.
onedayhen at

1
@Joe cross join는 항상 '기본값'입니다. 오라클은 명시 적으로 사용 되지 않는 한 열 이름과 일치 하지 않습니다natural join
Jack Douglas

1
  1. 큰 따옴표를 사용 "하면 데이터베이스의 기본 대소 문자를 무시하기 때문에 큰 따옴표를 사용하지 마십시오 . SQL 스펙에서는 모든 식별자를 대문자로 접어야합니다. PostgreSQL과 같은 일부 데이터베이스는 소문자로 접습니다. 인용 된 것이 없으면 모든 데이터베이스에서 작동하며 spec 또는 rdbms 관련 기본값으로 접을 수 있습니다.
  2. _위와 같이 밑줄 ( )을 사용하십시오 . camelCase를 사용해서는 안됩니다.
  3. {entity}_idID 및 해당 ID를 가리키는 외래 키에 사용하십시오 . 따라서 USING절을 사용할 수 있습니다 . 결합 조건에 사용되는 전역 고유 키 이름은 사양에 설정된 규칙입니다.

    SELECT *
    FROM employee
    INNER JOIN department
      USING (department_id);
    
      -- compare to
      ON employee.department_id = department.department_id;

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