데이터베이스의 열에 다음과 같이 레이블을 지정했습니다.
user_id
user_name
user_password_hash
두 테이블을 조인 할 때 충돌을 피하기 위해 테이블 별칭을 지정하는 방법에 대해 더 많이 배웠습니다.
데이터베이스에서 열에 레이블을 지정하는 효과적인 방법은 무엇입니까? 왜?
데이터베이스의 열에 다음과 같이 레이블을 지정했습니다.
user_id
user_name
user_password_hash
두 테이블을 조인 할 때 충돌을 피하기 위해 테이블 별칭을 지정하는 방법에 대해 더 많이 배웠습니다.
데이터베이스에서 열에 레이블을 지정하는 효과적인 방법은 무엇입니까? 왜?
답변:
귀하의 경우 접두사 사용자는 중복입니다. 우리 (담당자)는 이것이 테이블 사용자라는 것을 알고 있으므로 왜 user_
모든 필드 앞에 접두사를 추가 합니까?
내가 당신에게 제안하는 것은보다 자연스러운 접근 방식으로하는 것입니다.
사람의 특성은 무엇입니까 : 성, 이름, 생년월일, 국적 등.
자동차의 특성은 무엇입니까 : 모델, 연도, 색상, 에너지 등
당신의 칼럼은 가능한 한 자연 스러워야합니다. 그것은 당신과 당신을 따르는 모든 사람들에게 스키마를 더 명확하게 만들 것입니다. 이것을 유지 보수 단계라고도하며 유지 관리를보다 쉽게하기 위해 수행 할 수있는 모든 것이 일반적으로 노력할 가치가 있습니다.
Spredzy의 의견 외에도 기본 키에 동일한 (ID) 레이블을 지정하여 즉시 쿼리를 작성할 때 "국가 ID를 검색하지 않고 쉽게 (u.ID = c.ID)를 검색 할 수 있습니다. , country_ID, countries_ID, countriesID,? "
USING
절 을 사용하는 기능을 잃게됩니다 (사양에 위배됩니다).
데이터베이스 스키마에서 모든 열은 테이블에서 고유 한 이름을 가져야한다고 주장합니다. 몇 가지 이유가 있습니다.
모델링 관점에서 : 수프 속성으로 시작하여 테이블로 정규화합니다. 시간이 지남에 따라 비정규 화 또는 정규화 또는 추가 뷰 또는 구체화 된 뷰를 도입하거나 새 테이블을 도입 할 수 있습니다. 모든 열 이름이 고유 한 경우 문제가되지 않습니다.
이 조인 구문을 사용할 수 있습니다 : a JOIN b USING (a_id) JOIN c USING (a_id)
. 매우 편리하며 다음 사항을 도와줍니다.
조인이 많은 쿼리를 실행하거나을 사용하여 구체화 된 뷰를 만들면 SELECT *
충돌이 발생하지 않습니다. 가입 생각해 person.name
, product.name
, country.name
, 등 Urgh.
일반적으로 쿼리가 크면 id
어디에서나 의미 가 무엇인지 추적하기가 어렵습니다 .
예를 들어 다음과 같이 보일 것입니다.
USERS
----
id
username,
password
registration_date
테이블 이름을 대문자로 사용합니다. 이를 통해 테이블을 쉽게 식별 할 수 있습니다. 방금 이름을 지정한 열은 각각이 나타내는 것입니다. 숫자를 사용하지 않거나 접두사 또는 접미사를 포함시키지 마십시오. 이렇게하면 쿼리가 간단하고 간단 해집니다.
BTW, 나는 당신이 좋아하는 스타일을 찾아서 고수해야한다고 생각합니다. 자주 변경하면 더 복잡한 DB 스키마가 생깁니다.
다른 것과 마찬가지로 테이블 이름을 열의 일부로 포함하지 않는 것이 좋습니다. 열 이름이 대부분 비슷한 수백 개의 테이블이없는 한 : ID라는 열이있는 수십 개의 테이블이 모두 있으면 테이블 이름 앞에 접두사를 붙입니다.
최근에 개발자 중 한 명이 기본 키 및 외래 키 열 앞에 pk 및 fk를 붙이는 것을 선호하는 회사를 떠났습니다. 이로 인해 열이 pkfk (일반적으로 2 개의 열을 기반으로하는 복합 기본 키 중 하나는 다른 테이블의 외래 키임)로 시작되는 일부 가증이 발생합니다.
각 열 이름이 테이블 이름에서 파생 된 접두어로 시작하는 환경에서 일하고 있는데 내 발명은 아니지만 매우 만족합니다.
이상적으로 열 이름은 데이터베이스의 모든 테이블에서 고유합니다.
일부 관찰 :
일반적인 아이디어 : 가장 중요한 것은 각 명명 규칙의 일관성입니다.-단수와 복수 (열은 아닌 테이블에 적용됨)-기본 및 외래 키 식별 (데이터베이스의 내용과 구조를 구축)-일관성이있을 때 같은 문자열의 문자열과 짧은 변형을 저장합니다-플래그, 상태 등과 일치해야합니다.
Spredzy의 답변에 동의하지만 선호 사항에 따라 under_score 대신 camelCase를 사용한다고 덧붙입니다.
성, 성 등
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의 공식 옵션이 되었으면 일반적인 권장 사항은 사용하지 않는 것입니다. 열 이름이 잘못되면 문제가 생길 수 있기 때문에 좋은 열 이름을 옹호합니다.
NATURAL JOIN
결정적입니다.
cross join
는 항상 '기본값'입니다. 오라클은 명시 적으로 사용 되지 않는 한 열 이름과 일치 하지 않습니다natural join
"
하면 데이터베이스의 기본 대소 문자를 무시하기 때문에 큰 따옴표를 사용하지 마십시오 . SQL 스펙에서는 모든 식별자를 대문자로 접어야합니다. PostgreSQL과 같은 일부 데이터베이스는 소문자로 접습니다. 인용 된 것이 없으면 모든 데이터베이스에서 작동하며 spec 또는 rdbms 관련 기본값으로 접을 수 있습니다._
위와 같이 밑줄 ( )을 사용하십시오 . camelCase를 사용해서는 안됩니다.{entity}_id
ID 및 해당 ID를 가리키는 외래 키에 사용하십시오 . 따라서 USING
절을 사용할 수 있습니다 . 결합 조건에 사용되는 전역 고유 키 이름은 사양에 설정된 규칙입니다.
SELECT *
FROM employee
INNER JOIN department
USING (department_id);
-- compare to
ON employee.department_id = department.department_id;