문제

제가 궁금했던 사람에게 의견에 이름의 ID 를 열에서 데이터베이스 테이블이 있습니다.

이 있을 경우 테이블이라는 송장 기본 키의 id 열이 나는 열 InvoiceID 그래서 내가 충돌하지 않는 다른 테이블과 그것의 분명한 것입니다.

내가 있는 곳 workind 현재들은 그들이라는 모든 ID 열 ID 입니다.

그래서 그들은 수행하려면 다음과 같이 합니다:

Select  
    i.ID 
,   il.ID 
From
    Invoices i
    Left Join InvoiceLines il
        on i.ID = il.InvoiceID

지금,나는 여기에 몇 가지 문제가:
1.당신이 필요가 별칭에 열 선택
2.ID=InvoiceID 에 맞지 않는 내 뇌
3.지 않은 경우에는 별명은 테이블과 함 InvoiceID 그것은 분명한 어떤 테이블은?

무엇이 다른 사람의 생각은 주제에 대?

도움이 되었습니까?

해결책

ID는 SQL antipattern입니다. 보다 http://www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a

ID로 ID가있는 테이블이 많으면 훨씬 더 어렵게보고합니다. 그것은 의미를 가리고 복잡한 쿼리를 읽기가 더 어렵게 만들뿐만 아니라 보고서 자체를 구별하기 위해 별칭을 사용하도록 요구합니다.

또한 누군가가 사용 가능한 데이터베이스에서 자연스럽게 조인을 사용할 수있을만큼 어리석은 경우 잘못된 레코드에 가입하게됩니다.

일부 DBS가 허용하는 사용 구문을 사용하려면 ID를 사용할 수 없습니다.

ID를 사용하는 경우 조인 구문을 복사하는 경우 (아무도이 작업을 수행하지 않는다고 말하지 마십시오!) 결합 조건에서 별명을 변경하는 것을 잊어 버리면 잘못된 조인으로 쉽게 끝날 수 있습니다.

그래서 당신은 이제 가지고 있습니다

select t1.field1, t2.field2, t3.field3
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id

당신이 의미했을 때

select t1.field1, t2.field2, t3.field3 
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id

TableNameid를 ID 필드로 사용하는 경우 이러한 종류의 우발적 인 실수는 훨씬 적고 찾기가 훨씬 쉽습니다.

다른 팁

ID 열의 TableName + ID를 항상 선호 한 다음 외국 키의 경우 TableName + ID를 선호했습니다. 이렇게하면 모든 테이블은 ID 필드와 동일한 이름을 가지며 중복 설명이 없습니다. 모든 테이블의 기본 키 필드 이름을 갖기 때문에 이것은 나에게 더 간단 해 보입니다.

테이블에 가입하고 어떤 ID 필드가 어떤 테이블에 속한 지 알지 못하는 한, 내 의견으로는이 상황을 처리하기 위해 쿼리를 작성해야합니다. 내가 일하는 곳에서, 우리는 항상 테이블/테이블 별명과 함께 성명서에서 사용하는 필드를 준비합니다.

Theres 되는 괴상한 싸우는 이에 대해 매우 일 내에서 회사의 늦었습니다.의 출현 LINQ 은 중복 테이블+ID 패턴 더욱 분명히 바보 같은 내 눈에.나는 생각한 가장 합리적인 사람들이 말하는 경우에 당신은 손으로 쓰는 SQL 에서 같은 방법으로는 지정할 수 있는 테이블의 이름을 구분 FKs 그런 다음 그것은뿐만 아니라 절감에 입력하지만,추가 명확성을 SQL 을 사용하는 ID 에는 명확하게 볼 수 있는 PKFK.

E.g.

에서 직원들 e 왼쪽에 가입하는 고객의 c e.ID=c.EmployeeID

말 뿐만 아니라는 두 가지에 연결되지만,이는 PKFK.반면에서는 이전 스타일은 당신을 강요하거나 또는 희망이 그들이 지명되었습니다.

우리는 사용 InvoiceID, 아니다 ID. 쿼리를 더 읽기 쉽게 만듭니다 ID 혼자서는 무엇이든 의미 할 수 있습니다. 특히 테이블을 별조 할 때 i.

나는 테이블의 PK가 단순히 ID 여야하고 외국 키는 다른 테이블 + ID를 나열해야한다는 Keven과 몇몇 다른 사람들과 동의합니다.

그러나 나는 최근 에이 논쟁에 더 많은 무게를 준 한 가지 이유를 추가하고 싶습니다.

현재 위치에서 우리는 Poco Generation을 사용하여 엔티티 프레임 워크를 사용하고 있습니다. ID의 표준 이름 지정 규칙을 사용하여 PK는 유효성 검사를 통해 기본 POCO 클래스의 상속 및 공통 열 이름 세트를 공유하는 테이블에 대한 상속을 허용합니다. Tablename + ID를 각각의 각 테이블에 대한 PK로 사용하면 기본 클래스를 사용하는 기능이 파괴됩니다.

생각을위한 음식 만.

중요하지는 않습니다. 모든 이름 지정 규칙에서 Simalar 문제가 발생할 가능성이 높습니다.

그러나 일관성을 유지하는 것이 중요하므로 쿼리를 작성할 때마다 테이블 정의를 볼 필요가 없습니다.

내 취향은 또한 ID 에 대한 기본 키고 TableNameID 외국인을 위한 열쇠이다.또한 같은 열"이름"에서 대부분의 테이블은 곳 내가 사용자에 읽을 수 있는 식별자(즉이름:-))의 항목입니다.이 구조에 큰 유연성을 제공합 응용 프로그램 자체에서,나는 처리할 수 있는 테이블에서 질량에서,동일한 방법입니다.이 강력한 것입니다.일반적으로 OO 소프트웨어에 내장되어 최고의 데이터베이스하지만,OO 도구 세트에 적용할 수 없기 때문에 db 그 자체를 허용하지 않습니다.을 갖는 열의 id 및의 이름은 아직도 매우 좋지 않다,하지만 그것은 단계입니다.

선택
i.ID,il.ID 서 서 왼쪽 가입하세 InvoiceLines il i.ID=il.InvoiceID

왜한 절차를 밟으면 되나요?

Select  
    Invoices.ID 
,   InvoiceLines.ID 
From
    Invoices
    Left Join InvoiceLines
        on Invoices.ID = InvoiceLines.InvoiceID

내 생각에 이것은 아주 많이 읽고 간단합니다.이름 변수로 나는 일이 가난한 선택에 일반적입니다.

방금 "ID"만 사용하는 장소에서 일하기 시작했으며 (Core Tables에서 TableNameid가 외국 키에서 참조) 이미 그로 인해 발생하는 두 가지 생산 문제를 이미 발견했습니다.

어떤 경우에는 "... where id in (idectable에서 idid in (where in in) 대신 id in (where othertable에서 id를 선택하십시오 ...

잘못된 진술이 읽은 곳에서 "... 전송이있는 곳 (OtherTable에서 OtherTableID를 선택하십시오 ..."? 나는 생각하지 않습니다. 그래서.

다른 문제는 코드를 리팩토링 할 때 발생합니다. 이전에 쿼리가 핵심 테이블을 사용하는 반면, 임시 테이블을 사용하는 경우 이전 코드는 "... dbo.myfunction (t.id) ..."을 읽습니다. 임시 테이블 코어 테이블 대신 오류가 발생하지 않습니다. 오류가 발생합니다.

불필요한 오류를 생성하는 것이 목표라면 (일부 사람들이 일이 충분하지 않습니까?) 이런 종류의 이름 지정 규칙은 훌륭합니다. 그렇지 않으면 일관된 이름 지정이가는 길입니다.

단순화를 위해 대부분의 사람들은 테이블 ID의 열을 이름으로 지정합니다. 다른 테이블에 외국 키 참조가있는 경우, 결합의 경우 invoiceId (예제를 사용하기 위해)를 invoiceid라고 부릅니다.

공식적인 데이터 사전의 관점에서 나오면 데이터 요소의 이름을 지정합니다. invoice_ID. 일반적으로 데이터 요소 이름은 데이터 사전에서 고유하고 이상적으로는 전체적으로 동일한 이름을 가지지 만 때로는 추가 자격이있는 용어가 컨텍스트를 기반으로 필요할 수 있습니다. employee_ID 조직 차트에서 두 번 사용할 수 있으므로 supervisor_employee_ID 그리고 subordinate_employee_ID 각기.

분명히, 명명 규칙은 주관적이고 스타일의 문제입니다. ISO/IEC 11179 지침이 유용한 출발점이라고 생각합니다.

DBMS의 경우 테이블이 엔터테스 모음으로 보입니다 (예를 들어 코포 피그 테이블, 상수 테이블 등을 포함하는 것만 제외) employee_ID 키는 이름이 지정됩니다 Personnel. 그래서 곧바로 TableNameID 컨벤션은 나에게 효과가 없습니다.

나는 그것을 보았다 TableName.ID=PK TableNameID=FK 대형 데이터 모델에 사용되는 스타일과 약간 혼란 스럽다고 생각해야합니다. IE 전체에 걸쳐 식별자의 이름이 동일합니다. 즉, 어떤 테이블이 나타나는 테이블에 따라 이름을 변경하지 않습니다. 주목할만한 스타일은 앞서 언급 한 스타일이 다음과 같습니다. 추가하는 상점에서 사용됩니다 IDENTITY (자동 증가) 열로 모든 외국 키로 자연스럽고 복합 키를 피하는 동안 테이블. 이러한 상점은 공식적인 데이터 사전을 가지고 있지 않거나 데이터 모델을 구축하지 않는 경향이 있습니다. 다시 말하지만, 이것은 단지 스타일의 문제 일 뿐이며 개인적으로 구독하지 않는 문제입니다. 그래서 궁극적으로 그것은 나를위한 것이 아닙니다.

알 다시 말하면, 테이블 이름이 그렇게하는 컨텍스트를 제공 할 때 열 이름에서 예선을 삭제하는 경우를 볼 수 있습니다. employee_last_name 간단해질 수 있습니다 last_name 에서 Personnel 테이블. 여기서의 근거는 도메인이 '사람들의 성'이며 UNION에드 last_name~에서 외국 키로 사용하기보다는 다른 테이블 안에 또 다른 테이블이지만 다시 ... 나는 단지 내 마음을 바꿀 수도 있고 때로는 말할 수 없습니다. 데이터 모델링은 일부 예술, 과학입니다.

몸소 선호 (위에서 언급 한 바와 같이) 테이블 .idPK 그리고 TableIdFK. Microsoft Access도 이것을 추천합니다.

그러나 나는 또한 일부 생성 도구가 PK의 TableID를 선호한다는 사실도 알고 있습니다. 'ID' 말로, ID 포함 !!!

쿼리 디자이너조차도 Microsoft SQL Server에서이를 수행합니다 (그리고 생성 한 각 쿼리마다 열 ID의 모든 테이블에서 새로 생성 된 모든 관계를 제거합니다).

따라서 내 내부 OCD가 싫어하는 한 나는 TableId 협약. 데이터라고합니다 베이스, 앞으로 많은 많은 응용 프로그램이 희망적으로 기반이 될 것입니다. 그리고 모든 기술은 명확한 설명 스키마로 잘 정규화 된 이점을 제공해야합니다.

사람들이 TableName, Tabledescription 등을 사용하기 시작할 때 나는 내 선을 그린다는 것은 말할 필요도 없습니다. 제 생각에는 규칙은 다음을 수행해야합니다.

  • 테이블 이름 : 복수. 전. 직원
  • 테이블 별명 : 전체 테이블 이름, 단수화. 전.

    SELECT Employee.*, eMail.Address
    FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
    

업데이트

또한이 스레드에는 "관계"또는 역할로 인해 복제 된 열에 대한 유효한 게시물이 있습니다. 예를 들어, 상점에 an이있는 경우 Employeeid, 그것은 나에게 쪼그리고 앉는다. 그래서 나는 때때로 같은 일을합니다 store.employeeid_manager. 물론 조금 더 크지 만 레아에서 사람들은 찾아 내려고 미치지 않을 것입니다. 테이블 managerID, 또는 무엇을 Employeeid 거기에서하고 있습니다. 쿼리가 내가 그것을 단순화하는 위치에있을 때 : managerId에서 store에서 managerId로 selec

나는 당신이 일관된 한 "ID"에 무엇이든 사용할 수 있다고 생각합니다. 테이블 이름을 포함하는 것이 중요합니다. Erwin과 같은 모델링 도구를 사용하여 이름 지정 규칙 및 표준을 시행하므로 쿼리를 작성할 때 테이블 사이에 존재할 수있는 관계를 쉽게 이해할 수 있습니다.

첫 번째 진술이 의미하는 바는 ID 대신 'recno'와 같은 다른 것을 사용할 수 있다는 것입니다. 그러면이 테이블에는 invoice_recno의 pk가 있습니다.

건배, 벤

내 투표는 테이블 ID에 대한 인보이스드입니다. 또한 외국 키로 사용될 때 동일한 명명 규칙을 사용하고 쿼리에서 지능형 별명 이름을 사용합니다.

 Select Invoice.InvoiceID, Lines.InvoiceLine, Customer.OrgName
 From Invoices Invoice
 Join InvoiceLines Lines on Lines.InvoiceID = Invoice.InvoiceID
 Join Customers Customer on Customer.CustomerID = Invoice.CustomerID

물론, 그것은 다른 예보다 길다. 하지만 미소. 이것은 후손이며 언젠가는 일부 가난한 주니어 코더가 걸작을 바꿔야 할 것입니다. 이 예에서는 모호성이 없으며 추가 테이블이 쿼리에 추가되면 구동성에 감사 할 것입니다.

데이터베이스의 열 이름의 경우 "invoiceId"를 사용합니다.

필드를 LINQ를 통해 이름없는 구조물로 복사하면 구조의 유일한 ID라면 "ID"이름을 지정할 수 있습니다.

열이 외국 키에 사용되지 않으면 편집 또는 삭제를위한 행을 고유하게 식별하는 데만 사용되도록 "PK"라는 이름을 지정할 것입니다.

각 키에 "invoices.id"대신 "invoices.invoice_id"와 같은 고유 한 이름을 제공하는 경우 걱정없이 "자연 조인"및 "사용"연산자를 사용할 수 있습니다. 예를 들어

SELECT * FROM invoices NATURAL JOIN invoice_lines
SELECT * FROM invoices JOIN invoice_lines USING (invoice_id)

대신에

SELECT * from invoices JOIN invoice_lines
    ON invoices.id = invoice_lines.invoice_id

SQL은 더욱 장황하지 않고 충분히 장황합니다.

내가 무엇을 유지하는 것이 일관성을 위해 자신(여기서는 테이블의 단 열의 기본 키로 사용되는 ID)는 이름을 기본 키의 테이블 Table_pk.어디에서 나는 외국 열쇠를 가리키는 테이블 기본 키,전화 열 PrimaryKeyTable_fk.는 방법을 내가 알고 있는 경우 Customer_pk 고객 테이블과 Customer_fk 에서 내기 위해 테이블,나는 알기 위해 테이블 항목을 참조하여 고객에 있는 테이블.

나에게,이미 특히 조인 내가 생각하는 그것을 읽기 쉽습니다.

SELECT * 
FROM Customer AS c
    INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk

FWIW, 우리의 새로운 표준 (변경 사항은 모든 새로운 프로젝트와 함께 "Evolves"를 의미합니다)은 다음과 같습니다.

  • 소문자 데이터베이스 필드 이름
  • 대문자 테이블 이름
  • 밑줄을 사용하여 필드 이름으로 단어를 분리하십시오 - 코드로 파스칼 케이스로 변환하십시오.
  • pk_ 접두사는 기본 키를 의미합니다
  • _id 접미사는 정수, 자동 증가 ID를 의미합니다
  • fk_ 접두사는 외국 키를 의미합니다 (접미사가 필요 없음)
  • _VW 보기 용 접미사
  • is_ 부울에 대한 접두사

따라서 이름이라는 테이블에는 필드가있을 수 있습니다. pk_name_id, first_name, last_name, is_alive, 그리고 fk_company 그리고 불리는 견해 LIVING_CUSTOMERS_VW, :

SELECT first_name, last_name
FROM CONTACT.NAMES
WHERE (is_alive = 'True')

그러나 다른 사람들이 말했듯이, 거의 모든 계획은 일관성이 있고 의미를 불필요하게 난독 화하지 않는 한 작동 할 것입니다.

나는 당신이주는 이유에 대해 정확히 ID 필드 이름에 테이블 이름을 포함시키는 것에 동의합니다. 일반적으로 이것은 테이블 이름을 포함 할 유일한 필드입니다.

나는 평범한 ID 이름을 싫어합니다. 나는 항상 invoice_id 또는 그 변형을 사용하는 것을 선호합니다. 필요한 경우 ID의 권위있는 테이블이 어느 테이블인지 항상 알고 있지만 이것은 나를 혼란스럽게합니다.

SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceID = inv.ID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceLineID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceLineID = inv.ID 

무엇보다도 최악의 상황은 당신이 언급 한 믹스, 완전히 혼란스러운 것입니다. 가장 많이 사용되는 ID 중 하나를 제외하고는 거의 항상 foo_id 인 데이터베이스와 협력해야했습니다. 그것은 완전히 지옥이었다.

DomainName을 선호합니다 || 'ID'. (IE DomainName + ID)

DomainName은 종종 TableName과 동일하지만 항상 그런 것은 아닙니다.

ID 자체의 문제는 그것이 상향 조정되지 않는다는 것입니다. 약 200 개의 테이블이 있으면 각각 ID라는 첫 번째 열이있는 경우 데이터가 모두 비슷해 보이기 시작합니다. 항상 테이블 이름으로 ID 자격을 갖추면 약간 도움이되지만 그다지 많지는 않습니다.

DomainName & ID는 기본 키뿐만 아니라 외래 키를 지정하는 데 사용될 수 있습니다. foriegn 키의 이름을 참조하는 열에 이름을 따서 명명 될 때, 그것은 니모닉 지원 일 수 있습니다. 공식적으로, 외국 키의 이름을 IT 참조 키에 묶는 것은 필요하지 않습니다. 참조 무결성 제약 조건이 참조를 설정하기 때문입니다. 그러나 쿼리와 업데이트를 읽는 데있어 끔찍하게 편리합니다.

때때로, domainName || 동일한 이름의 동일한 테이블에 두 개의 열이 있기 때문에 'ID'는 사용할 수 없습니다. 예 : Employeeeid 및 Employees.supervisorid. 이 경우 rolename ||를 사용합니다 예에서와 같이 'ID'.

마지막으로, 가능한 경우 합성 키보다는 천연 키를 사용합니다. 자연 키를 사용할 수 없거나 신뢰할 수없는 상황이 있지만 자연 키가 올바른 선택 인 상황이 많이 있습니다. 그러한 경우, 나는 자연스러운 키가 자연스럽게 가지고있는 이름을 가져갔습니다. 이 이름에는 종종 문자 'ID'가 없습니다. 예 : Orderno NO는 "숫자"에 대한 약어입니다.

각 테이블에 대해 나는 나무 문자 속기를 선택합니다 (예 : 직원 => emp)

이렇게하면 숫자 Autonumber 기본 키가됩니다 nkemp.

전체 데이터베이스에서는 짧고 독특하며 그 속성을 한 눈에 정확히 알고 있습니다.

나는 동일한 이름을 SQL과 내가 사용하는 모든 언어 (대부분 C#, JavaScript, VB6)로 유지합니다.

Interakt 사이트를 참조하십시오 이름 지정 규칙 이름 지정 테이블과 열의 잘 생각 된 시스템. 이 방법은 각 테이블의 접미사를 사용합니다 (_prd 제품 테이블의 경우 또는 _ctg 카테고리 테이블의 경우) 및 주어진 테이블의 각 열에 추가하십시오. 그래서 제품 테이블의 ID 열은 id_prd 따라서 데이터베이스에서 독특합니다.

그들은 외국 키를 이해하는 데 도움을주기 위해 한 걸음 더 나아갑니다 : 카테고리 테이블을 나타내는 제품 테이블의 외국 키는 다음과 같습니다. idctg_prd 그것이 어떤 테이블에 속하는지 명백하도록 (_prd 접미사) 및이 테이블은 (카테고리)를 나타냅니다.

장점은 다른 테이블의 ID 열에 모호성이 없으며 쿼리가 열 이름에 의해 참조되는 컬럼을 한눈에 알 수 있다는 것입니다.

또한 참조하십시오 1 차 키/외국 키 명명 규칙

다음 이름 지정 규칙을 사용할 수 있습니다. 결함이 있지만 특정 문제를 해결합니다.

  1. 테이블 이름, 즉 송장에 짧은 (3-4 자) 별명을 사용하십시오. inv, 인보이스 라인 - invl
  2. 해당 닉네임을 사용하여 테이블의 열을 지정하십시오. inv_id, invl_id
  3. 참조 열에 사용합니다 invl_inv_id 이름을 위해.

이런 식으로 당신은 말할 수 있습니다

SELECT * FROM Invoice LEFT JOIN InvoiceLines ON inv_id = invl_inv_id
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top