응용 프로그램 개발자의 데이터베이스 개발 실수


566

응용 프로그램 개발자가 저지른 일반적인 데이터베이스 개발 실수는 무엇입니까?


답변:


1002

1. 적절한 지수를 사용하지 않음

이것은 비교적 쉬운 방법이지만 여전히 항상 발생합니다. 외래 키에는 인덱스가 있어야합니다. 필드를 사용하는 WHERE경우 색인이 있어야합니다. 이러한 인덱스는 종종 실행해야하는 쿼리를 기반으로 여러 열을 포함해야합니다.

2. 참조 무결성을 강제하지 않음

데이터베이스는 여기에서 다를 수 있지만 데이터베이스가 참조 무결성을 지원하는 경우 (모든 외래 키가 존재하는 엔터티를 가리킬 수 있음을 의미하는 경우) 사용해야합니다.

MySQL 데이터베이스에서이 실패를 보는 것이 일반적입니다. 나는 MyISAM이 그것을 지원한다고 생각하지 않습니다. InnoDB는 않습니다. MyISAM을 사용하거나 InnoDB를 사용하지만 사용하지 않는 사람들을 찾을 수 있습니다.

여기 더 :

3. 대리 (기술적) 기본 키가 아닌 자연 키 사용

자연 키는 (명시 적으로) 고유 한 외부 적으로 의미있는 데이터를 기반으로하는 키입니다. 일반적인 예로는 제품 코드, 2 자리 상태 코드 (미국), 주민등록번호 등이 있습니다. 대리 또는 기술 기본 키는 시스템 외부에서 전혀 의미가없는 키입니다. 그것들은 순수하게 엔티티를 식별하기 위해 발명되었으며 일반적으로 자동 증가 필드 (SQL Server, MySQL 등) 또는 시퀀스 (주로 Oracle)입니다.

내 의견으로는 항상 대리 키를 사용해야합니다. 이 문제는 다음과 같은 질문에서 나타났습니다.

이것은 당신이 보편적 인 동의를 얻지 못할 다소 논쟁적인 주제입니다. 자연스러운 키가 어떤 상황에서는 괜찮다고 생각하는 사람들이 있지만, 대리 키에 대한 비판은 의심 할 여지없이 불필요합니다. 당신이 저에게 묻는다면 그것은 아주 작은 단점입니다.

유고 슬라비아 와 같은 국가존재하지 않을 수 있습니다 .

4. DISTINCT작동 해야하는 쿼리 작성

ORM 생성 쿼리에서 종종이 문제가 나타납니다. 최대 절전 모드의 로그 출력을 보면 모든 쿼리가 다음과 같이 시작됩니다.

SELECT DISTINCT ...

이것은 중복 행을 반환하지 않으므로 중복 객체를 얻도록하는 약간의 지름길입니다. 때때로 사람들도이 일을하는 것을 보게 될 것입니다. 당신이 그것을 너무 많이 보면 그것은 진짜 붉은 깃발입니다. 하지 그DISTINCT 나쁜 또는 유효한 응용 프로그램이 없습니다. 그것은 (두 가지 모두에서) 수행하지만 올바른 쿼리를 작성하기위한 대리 또는 정지가 아닙니다.

에서 내가 DISTINCT 증오하는 이유 :

내 의견으로는 상황이 악화되기 시작하는 곳은 개발자가 실질적인 쿼리를 작성하고 테이블을 결합 할 때 갑자기 중복 (또는 더 많은) 행과 즉각적인 응답을 얻는 것처럼 보입니다 . 이 "문제"에 대한 그의 "해결책"은 DISTINCT 키워드를 던지고 그의 모든 문제는 사라집니다.

5. 조인에 대한 집계 선호

데이터베이스 응용 프로그램 개발자의 또 다른 일반적인 실수는 GROUP BY조인과 비교할 때 훨씬 더 비싼 집계 (즉, 절)를 인식하지 못하는 것 입니다.

이것이 얼마나 널리 퍼져 있는지에 대한 아이디어를 제공하기 위해이 주제에 대해 여러 번 글을 썼으며 많은 찬사를 받았습니다. 예를 들면 다음과 같습니다.

에서 SQL 문 - "로와 가진 그룹"대 "가입" :

첫 번째 질문 :

SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3

쿼리 시간 : 0.312 초

두번째 질문 :

SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1

쿼리 시간 : 0.016s

맞습니다. 내가 제안한 조인 버전 은 집계 버전보다 20 배 빠릅니다.

6. 뷰를 통해 복잡한 쿼리를 단순화하지 않음

모든 데이터베이스 공급 업체가 뷰를 지원하는 것은 아니지만 뷰를 지원하는 경우 신중하게 사용하면 쿼리를 크게 단순화 할 수 있습니다. 예를 들어 한 프로젝트 에서 CRM에 일반 당사자 모델 을 사용했습니다 . 이것은 매우 강력하고 유연한 모델링 기술이지만 많은 조인을 유발할 수 있습니다. 이 모델에는 다음이있었습니다.

  • : 사람과 조직;
  • 당사자 역할 : 해당 당사자가 수행 한 작업 (예 : 직원 및 고용주)
  • 당사자 역할 관계 : 해당 역할이 서로 관련되는 방식.

예:

  • 테드는 당사자의 하위 유형 인 개인입니다.
  • Ted에는 많은 역할이 있으며 그 중 하나는 Employee입니다.
  • 인텔은 당사국의 하위 유형 인 조직입니다.
  • 인텔에는 많은 역할이 있으며 그 중 하나는 고용주입니다.
  • 인텔은 Ted를 사용합니다. 즉, 각 역할간에 관계가 있습니다.

그래서 테드와 그의 고용주를 연결하기 위해 5 개의 테이블이 합쳐졌습니다. 모든 직원이 조직이 아닌 개인이라고 가정하고 다음과 같은 도우미보기를 제공합니다.

CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id

그리고 갑자기 원하는 데이터를 매우 간단하게 볼 수 있지만 매우 유연한 데이터 모델을 볼 수 있습니다.

7. 입력을 소독하지 않음

이것은 큰 것입니다. 이제는 PHP가 마음에 들지만 수행중인 작업을 모르는 경우 공격에 취약한 사이트를 만드는 것이 매우 쉽습니다. 작은 바비 테이블 이야기 보다 더 좋은 것은 없습니다. .

URL, 양식 데이터 및 쿠키 를 통해 사용자가 제공 한 데이터 는 항상 적대적이고 위생적인 ​​것으로 취급해야합니다. 당신이 기대하는 것을 얻고 있는지 확인하십시오.

8. 준비된 진술을 사용하지 않음

준비된 명령문은 쿼리에서 삽입, 업데이트 및 WHERE절에 사용 된 데이터를 뺀 후 나중에이를 제공 할 때입니다. 예를 들면 다음과 같습니다.

SELECT * FROM users WHERE username = 'bob'

vs

SELECT * FROM users WHERE username = ?

또는

SELECT * FROM users WHERE username = :username

플랫폼에 따라 다릅니다.

이 작업을 수행하여 데이터베이스가 무릎을 꿇는 것을 보았습니다. 기본적으로 최신 데이터베이스에 새로운 쿼리가 발생할 때마다 컴파일해야합니다. 이전에 본 쿼리가 발견되면 데이터베이스에 컴파일 된 쿼리와 실행 계획을 캐시 할 수있는 기회를 제공합니다. 쿼리를 많이 수행하면 데이터베이스에이를 파악하고 그에 따라 최적화 할 수 있습니다 (예 : 컴파일 된 쿼리를 메모리에 고정).

준비된 문을 사용하면 특정 쿼리가 얼마나 자주 사용되는지에 대한 의미있는 통계가 제공됩니다.

준비된 명령문은 또한 SQL 삽입 공격으로부터 사용자를 더 잘 보호합니다.

9. 충분히 정규화하지 않음

데이터베이스 정규화 는 기본적으로 데이터베이스 디자인을 최적화하는 프로세스 또는 데이터를 테이블로 구성하는 방법입니다.

이번 주에 누군가가 배열을 파기하여 데이터베이스의 단일 필드에 삽입하는 코드를 발견했습니다. 정규화하면 해당 배열의 요소를 자식 테이블의 별도 행으로 처리합니다 (즉, 일대 다 관계).

이것은 또한 사용자 ID 목록을 저장하는 최상의 방법으로 나타 났습니다 .

다른 시스템에서 목록이 직렬화 된 PHP 배열에 저장되어 있음을 보았습니다.

그러나 정규화 부족은 여러 형태로 나타납니다.

더:

10. 너무 많은 정규화

이것은 이전 시점과 모순되는 것처럼 보이지만 많은 것들과 마찬가지로 정규화는 도구입니다. 그것은 목적 자체가 아니라 목적을위한 수단이다. 많은 개발자들이 이것을 잊고 "의미"를 "끝"으로 취급하기 시작한다고 생각합니다. 단위 테스트는 이것의 대표적인 예입니다.

한때 클라이언트와 같은 거대한 계층 구조를 가진 시스템에서 일했습니다.

Licensee ->  Dealer Group -> Company -> Practice -> ...

따라서 의미있는 데이터를 얻기 전에 약 11 개의 테이블을 결합해야했습니다. 정규화가 너무 멀리 취해진 좋은 예였습니다.

요컨대, 신중하고 고려 된 비정규 화는 성능상의 이점이 크지 만이를 수행 할 때는 실제로주의해야합니다.

더:

11. 전용 아크 사용

배타적 아크는 둘 이상의 외래 키를 사용하여 테이블을 만들 때 흔히 발생하는 실수입니다. 단 하나의 키만 null이 될 수 없습니다. 큰 실수. 우선 데이터 무결성을 유지하는 것이 훨씬 더 어려워집니다. 결국 참조 무결성이 있어도 둘 이상의 외래 키가 설정되는 것을 막을 수있는 것은 없습니다 (복잡한 검사 제한 조건에도 불구하고).

에서 관계형 데이터베이스 디자인에 대한 실용 가이드 :

코드를 작성하기가 어려울 수 있고 유지 보수가 더 어려울 수 있기 때문에 가능한 한 독점적 아크 구성에 대해 강력히 권고했습니다.

12. 쿼리에 대한 성능 분석을 전혀하지 않음

실용주의는 특히 데이터베이스 세계에서 지배적입니다. 원칙이 교리가되었다는 원칙을 고수한다면 실수를 저지른 것입니다. 위에서 집계 쿼리 예제를 보자. 집계 버전은 "좋아"보일 수 있지만 성능은 좋지 않습니다. 퍼포먼스 비교는 논쟁을 끝내야했지만 (그러나 그렇게하지는 않았다), 우선 잘못된 정보에 대한 견해를 내뿜는 것은 무지하고 위험하다.

13. UNION ALL, 특히 UNION 구조에 대한 과도한 의존

SQL 용어의 UNION은 일치하는 데이터 세트를 연결하기 때문에 동일한 유형 및 개수의 열을 갖습니다. 이들의 차이점은 UNION ALL은 간단한 연결이며 가능한 한 선호되는 반면 UNION은 중복 튜플을 제거하기 위해 암시 적으로 DISTINCT를 수행합니다.

DISTINCT와 같은 UNION도 그 자리에 있습니다. 유효한 응용 프로그램이 있습니다. 그러나 특히 하위 쿼리에서 많은 작업을 수행하는 경우 무언가 잘못되었을 수 있습니다. 쿼리 구성이 잘못되었거나 데이터 모델이 잘못 설계되어 이러한 작업을 수행해야 할 수 있습니다.

UNION은 특히 조인 또는 종속 하위 쿼리에 사용될 때 데이터베이스를 손상시킬 수 있습니다. 가능할 때마다 피하십시오.

14. 쿼리에서 OR 조건 사용

이것은 무해한 것처럼 보일 수 있습니다. 결국 AND는 정상입니다. 아니면 괜찮을까요? 잘못된. 기본적으로 AND 조건 은 데이터 세트를 제한 하는 반면 OR 조건 데이터 세트 를 늘리지 만 최적화에 적합하지는 않습니다. 특히 다른 OR 조건이 교차 할 때 옵티마이 저가 결과에 대해 DISTINCT 조작을 효과적으로 수행하도록 할 수 있습니다.

나쁜:

... WHERE a = 2 OR a = 5 OR a = 11

보다 나은:

... WHERE a IN (2, 5, 11)

이제 SQL 최적화 프로그램이 첫 번째 쿼리를 두 번째 쿼리로 효과적으로 전환 할 수 있습니다. 그러나 그렇지 않을 수도 있습니다. 하지 마십시오.

15. 고성능 솔루션에 적합하도록 데이터 모델을 설계하지 않음

이것은 정량화하기 어려운 포인트입니다. 일반적으로 그 효과에 의해 관찰됩니다. 비교적 간단한 작업에 대한 형편없는 쿼리를 작성하거나 비교적 간단한 정보를 찾기위한 쿼리가 효율적이지 않으면 데이터 모델이 좋지 않을 수 있습니다.

어떤면에서는이 점이 이전의 모든 것을 요약하지만 쿼리 최적화와 같은 작업은 종종 두 번째로 수행해야 할 때 먼저 수행된다는 것이 더 조심스러운 이야기입니다. 무엇보다도 성능을 최적화하기 전에 올바른 데이터 모델이 있는지 확인해야합니다. 크 누스가 말했듯이 :

조기 최적화는 모든 악의 근원입니다

16. 데이터베이스 트랜잭션의 잘못된 사용

특정 프로세스에 대한 모든 데이터 변경은 원자 적이어야합니다. 즉, 작업이 성공하면 완전히 수행됩니다. 실패하면 데이터는 변경되지 않습니다. - '반 완료'변경 가능성이 없어야합니다.

가장 간단한 방법은 전체 시스템 설계가 단일 INSERT / UPDATE / DELETE 문을 통해 모든 데이터 변경을 지원하도록 노력하는 것입니다. 이 경우 데이터베이스 엔진이 자동으로 수행해야하므로 특별한 트랜잭션 처리가 필요하지 않습니다.

그러나 프로세스가 데이터를 일관성있는 상태로 유지하기 위해 하나의 단위로 여러 명령문을 수행해야하는 경우 적절한 트랜잭션 제어가 필요합니다.

  • 첫 번째 진술 전에 거래를 시작하십시오.
  • 마지막 진술 후 거래를 완결하십시오.
  • 오류가 발생하면 트랜잭션을 롤백하십시오. 그리고 매우 NB! 오류 뒤에 나오는 모든 명령문을 건너 뛰거나 중단하는 것을 잊지 마십시오.

이와 관련하여 데이터베이스 연결 계층 및 데이터베이스 엔진이 상호 작용하는 방식의 하위 조직에도주의를 기울이는 것이 좋습니다.

17. '세트 기반'패러다임을 이해하지 못한다

SQL 언어는 특정 종류의 문제에 적합한 특정 패러다임을 따릅니다. 다양한 공급 업체별 확장에도 불구하고이 언어는 Java, C #, Delphi 등의 언어에서 사소한 문제를 해결하기 위해 어려움을 겪고 있습니다.

이러한 이해 부족은 몇 가지 방식으로 나타납니다.

  • 데이터베이스에 너무 많은 절차 적 또는 명령 적 논리를 부적절하게 부과합니다.
  • 커서가 부적절하거나 과도하게 사용되었습니다. 특히 단일 쿼리로 충분할 때.
  • 여러 행 업데이트에서 영향을받는 행당 한 번만 트리거가 발생한다고 잘못 가정합니다.

명확한 책임 분담을 결정하고 각 문제를 해결하기 위해 적절한 도구를 사용하도록 노력하십시오.


9
외래 키에 대한 MySQL의 진술에 따르면 MyISAM이이를 지원하지 않는 것이 맞습니다. 그러나 MyISAM을 사용하는 것만으로는 나쁜 디자인임을 암시합니다. 내가 MyISAM을 사용한 이유는 InnoDB가 FullText 검색을 지원하지 않기 때문에 불합리하다고 생각하지 않기 때문입니다.
Derek H

1
# 6에 대해 물어봐야합니다. 이와 같은 뷰를 사용하는 것이 내가 가장 좋아하는 일 중 하나이지만 최근에 기본 테이블의 MySQL 인덱스를 사용하면 뷰의 구조가 병합 알고리즘을 사용할 수있는 경우에만 순종한다는 것을 알게되었습니다. 그렇지 않으면 임시 테이블이 사용되고 모든 인덱스가 쓸모가 없습니다. 많은 작업으로 인해이 동작이 발생한다는 것을 알면 훨씬 더 놀랍습니다. .01 초 쿼리를 100 초 쿼리로 전환하는 좋은 방법입니다. 여기 다른 사람이 이것에 경험이 있습니까? 다음 코멘트에서 링크를 확인하십시오.
피터 베일리

5
# 3에 완전히 동의하지 않습니다. 예, 국가는 존재하지 않을 수 있지만 국가 코드는 계속 동일한 것을 나타냅니다. 통화 코드 또는 미국과 동일합니다. 이러한 경우 대리 키를 사용하는 것이 멍청하며 추가 조인을 포함해야하므로 쿼리에 더 많은 오버 헤드가 발생합니다. 나는 당신이 말을 안전 말할 것이다 아마 사용자 별 데이터 (따라서가 아니라 국가, 통화 및 미국 주)에 대한 대리를 사용하도록해야한다.
Thomas

1
RE : # 11 데이터 무결성을 강화하는 데 필요한 검사 제약 조건은 간단합니다. 이러한 설계를 피해야하는 다른 이유가 있지만 "복잡한"검사 제한 조건이 필요한 것은 아닙니다.
토마스

2
# 3으로 당신은 정직하지 않습니다. 인공 키에는 "필요하지 않을 수도 있습니다"보다 단점이 더 많습니다. 특히, 자연 키를 사용하면 테이블의 데이터가 디스크에 기록되는 순서를 제어 할 수 있습니다. 테이블을 쿼리하는 방법을 알고 있으면 동시에 액세스 할 수있는 행이 같은 페이지에서 끝나도록 인덱스 할 수 있습니다. 또한 고유 한 복합 인덱스를 사용하여 데이터 무결성을 강화할 수 있습니다. 이것이 필요한 경우 인공 키 인덱스 외에 추가해야합니다. 상기 복합 지수가 귀하의 pkey 인 경우 하나의 돌로 2 마리의 새가 죽었습니다.
Shane H

110

개발자의 주요 데이터베이스 설계 및 프로그래밍 실수

  • 이기적인 데이터베이스 디자인 및 사용법. 개발자는 종종 데이터의 다른 이해 관계자의 요구를 고려하지 않고 데이터베이스를 개인 영구 객체 저장소로 취급합니다. 이것은 응용 프로그램 설계자에게도 적용됩니다. 데이터베이스 설계 및 데이터 무결성이 좋지 않으면 데이터 작업을하는 타사가 어렵게되어 시스템의 수명주기 비용이 크게 증가 할 수 있습니다. 보고 및 MIS는 응용 프로그램 설계에있어 사촌이 좋지 않은 경향이 있으며 나중에 생각해야합니다.

  • 비정규 화 된 데이터 남용. 비정규 화 된 데이터를 과도하게 사용하고 응용 프로그램 내에서 유지 관리하는 것은 데이터 무결성 문제의 레시피입니다. 비정규 화는 드물게 사용하십시오. 쿼리에 조인을 추가하지 않으려는 것이 비정규 화의 변명이 아닙니다.

  • SQL 작성이 두렵습니다. SQL은 로켓 과학이 아니며 실제로 업무를 잘 수행합니다. O / R 매핑 계층은 단순하고 해당 모델에 잘 맞는 95 %의 쿼리를 수행하는 데 매우 능숙합니다. 때로는 SQL이 작업을 수행하는 가장 좋은 방법입니다.

  • 독단적 '저장 절차 없음'정책. 저장 프로 시저가 악하다고 생각하는지 여부에 관계없이 이러한 종류의 독단적 태도는 소프트웨어 프로젝트에 적용되지 않습니다.

  • 데이터베이스 디자인을 이해하지 못합니다. 정규화는 당신의 친구이며 로켓 과학아닙니다. 조인과 카디널리티는 매우 간단한 개념입니다. 데이터베이스 응용 프로그램 개발에 관여하는 경우이를 이해하지 못하는 이유는 없습니다.


2
트랜잭션은 트랜잭션 데이터베이스 및보고에서 수행되어야하며 MIS는 별도의 분석 데이터베이스에서 수행되어야한다고 주장 할 수 있습니다. 따라서 두 세계의 장점을 모두 누리고 모든 사람들이 행복합니다 (데이터 변환 스크립트를 작성하여 전자를 작성해야하는 가난한 머그잔 제외).
Chris Simpson

시스템의 데이터를 사용하는 사람, MIS 응용 프로그램의 품질이 좋지 않은 데이터, 소스에 실제로 기록되지 않았기 때문에 ETL을 작성하는 머그잔뿐만 아니라 MIS 응용 프로그램의 품질이 낮은 데이터 열악한 데이터 품질로부터
ConcernedOfTunbridgeWells

포인트 1에 더 동의하지 않을 수 있습니다. 데이터베이스는 지속성을위한 것이며 프로세스 간 통신을위한 것이 아닙니다. 거의 항상 그 문제에 대한 더 나은 해결책이 있습니다. 명시적인 요구 사항이 없으면 응용 프로그램을 제외한 다른 사람이 데이터베이스를 사용하지 않는 것처럼 데이터베이스를 처리해야합니다. 명백한 요구 사항이 있더라도 사용자 스토리와 근본 원인 분석을 수행하면 요청자의 의도를 채우는 훨씬 더 나은 방법을 발견하게 될 것입니다. 그런 다음 CQRS라는 문구가 다소 일반적인 회사에서 일합니다
George Mauer

3
간단한 예 : 저는 보험 정책 관리 시스템을 보유하고 있으며 잠재적 회복을 계산하기 위해 5 백만 건의 청구 상태를 양보 된 재보험 시스템에로드해야합니다. 시스템은 구형 클라이언트-서버 COTS 패키지로, 구형 메인 프레임 시스템과도 인터페이스하도록 설계되었습니다. 재무 관리 목적을 위해 둘 다 조정해야합니다. 이 작업은 한 달에 한 번 수행됩니다. 당신의 논리에 따라 요구 사항을 정의하는 일련의 사용자 스토리를 작성하고 공급 업체에게 기존 제품에 웹 서비스 래퍼를 추가하는 것에 대해 인용하도록 요청합니다.
ConcernedOfTunbridgeWells

2
그런 다음 DBA가 게 으르거나 무능합니다.
ConcernedOfTunbridgeWells

80
  1. 데이터베이스 스키마에서 버전 제어를 사용하지 않음
  2. 라이브 데이터베이스에 대해 직접 작업
  3. 고급 데이터베이스 개념 (인덱스, 클러스터형 인덱스, 제약 조건, 구체화 된 뷰 등)을 읽고 이해하지 않음
  4. 확장 성 테스트 실패 ... 3 행 또는 4 행의 테스트 데이터만으로는 실제 라이브 성능의 실제 그림을 얻을 수 없습니다.

1
두 번째로 # 1과 # 2가 무겁습니다. DB를 변경할 때마다 스키마를 덤프하고 버전을 변경합니다. 나는 세 개의 데이터베이스 설정, 개발자 하나, 준비 하나, 그리고 살아있는 하나를 가지고 있습니다-아무것도 라이브 데이터베이스에서 "테스트"되지 않습니다!
Ixmatus

Red Gate에서는 SQL Source Control로 첫 번째 포인트를 향상시키기위한 단계를 수행했습니다! 내가 조사하는 동안 대화에서 사람들은 더 이상 프로덕션 데이터베이스에 대해 개발하고 있지 않지만 일반적으로 개발 환경으로 돌아가는 "비상"수정 사항이 종종 발생합니다. 이는 또 다른 문제입니다.
David Atkinson

46

저장 프로 시저에 대한 과도한 사용 및 / 또는 의존

일부 응용 프로그램 개발자는 저장 프로 시저를 중간 계층 / 프런트 엔드 코드의 직접 확장으로 간주합니다. 이것은 Microsoft 스택 개발자에게 공통적 인 특징으로 보이며 (하나이지만 성장했습니다) 복잡한 비즈니스 논리 및 워크 플로 처리를 수행하는 많은 저장 프로 시저를 생성합니다. 이것은 다른 곳에서 훨씬 잘 수행됩니다.

저장 프로시 저는 실제 기술 요소 중 일부 (예 : 성능 및 보안)를 사용해야한다는 사실이 실제로 입증 된 경우에 유용합니다. 예를 들어, 대규모 데이터 세트의 집계 / 필터링을 "데이터에 가깝게"유지하십시오.

최근에는 비즈니스 로직과 규칙의 70 %가 1400 SQL Server 저장 프로 시저 (나머지 UI 이벤트 처리기)에서 구현 된 대규모 Delphi 데스크톱 응용 프로그램을 유지 관리하고 향상시켜야했습니다. TSQL에 효과적인 단위 테스트를 도입하기가 어렵고, 캡슐화가 부족하고 도구 (디버거, 편집자)가 부족하기 때문에 이는 악몽이었습니다.

과거에 Java 팀과 함께 일하면서 나는 그 환경에서 종종 완전히 반대되는 것을 발견했습니다. Java Architect는 "데이터베이스는 코드가 아니라 데이터를위한 것"이라고 말했습니다.

요즘에는 저장된 proc를 전혀 고려하지 않는 것이 실수라고 생각하지만 유용한 이점을 제공하는 상황에서는 기본적으로 아예 사용하지 않아야합니다 (다른 답변 참조).


4
저장 프로시 저는 사용되는 프로젝트에서 상처를 입는 경향이 있으므로 일부 개발자는 "저장 프로 시저 없음"규칙을 만듭니다. 그래서 그들 사이에 열린 갈등이있는 것 같습니다. 당신의 대답은 실제로 어떤 방법을 선택해야하는지 또는 다른 방법을 선택해야하는 경우에 적합합니다.
Warren P

이점 : 보안-응용 프로그램에 "삭제 *에서 ..."기능을 제공 할 필요가 없습니다. 조정-DBA는 전체 애플리케이션을 재 컴파일 / 배포하지 않고도 쿼리를 조정할 수 있습니다. 분석-데이터 모델을 변경 한 후에도 여전히 유효한지 확인하기 위해 많은 프로세스를 쉽게 다시 컴파일 할 수 있습니다. 마지막으로, SQL이 응용 프로그램이 아닌 데이터베이스 엔진에 의해 실행되는 것을 고려하면 "데이터베이스는 코드가 아니라 데이터를위한 것"이라는 개념이 지체됩니다.
NotMe

그렇다면 UI에 비즈니스 로직을 포함시킬 것입니다. UI는 조작되는 데이터와 분리되어 있습니까? 특히 데이터 조작이 UI에서 왕복하는 것이 아니라 데이터베이스 서버에서 수행 할 때 가장 효율적이기 때문에 이것은 좋은 생각처럼 보이지 않습니다. 또한 데이터를 제어하는 ​​데이터베이스에 의존 할 수없고 다른 데이터 조작이 진행되는 다른 버전의 UI가있을 수 있으므로 응용 프로그램을 제어하기가 더 어렵다는 것을 의미합니다. 안좋다. 저장 프로 시저를 제외하고는 내 데이터를 건드리지 않습니다.
David T. Macknet

비즈니스 로직을 UI에서 분리해야하는 경우 멀티 티어 아키텍처를 사용할 수 있습니다. 또는 다른 앱 / UI에서 사용하는 비즈니스 객체와 논리가있는 라이브러리입니다. 저장 프로시 저는 데이터 / 비즈니스 로직을 특정 데이터베이스에 고정하므로이 경우 데이터베이스를 변경하면 비용이 많이 듭니다. 그리고 막대한 비용이 나쁘다.
너무

@too : 대부분의 경우 데이터베이스를 변경하는 것은 비용이 많이 듭니다. 특정 DBMS가 제공하는 성능 및 보안 기능을 잃어 버릴 염려가 없습니다. 또한 계층이 추가되면 복잡성이 증가하고 성능이 저하되며 추가 언어는 특정 언어와 연결됩니다. 마지막으로, 사용중인 언어가 데이터베이스 서버보다 변경 될 가능성이 높습니다.
NotMe

41

첫번째 문제? 장난감 데이터베이스에서만 테스트합니다. 따라서 데이터베이스가 커지면 SQL이 크롤링된다는 것을 전혀 모릅니다. 누군가가 와서 나중에 고쳐야합니다 (들리는 소리는 내 이빨입니다).


2
데이터베이스의 크기는 관련이 있지만 더 큰 문제는로드입니다. 실제 데이터 세트를 테스트하더라도 데이터베이스가 프로덕션로드 상태 일 때 쿼리 성능을 테스트하지 않습니다.
davidcl

데이터베이스 크기가로드보다 큰 문제라고 말하고 싶습니다. 테스트 동안 결코하고 성능 문제, 메모리에 있기 때문에 전체 데이터베이스에 맞게 - 나는 중요한 인덱스가 없어진 것을 여러 번 보았다
다뉴브 선원에게


28

상관 된 하위 쿼리로 인한 성능 저하

대부분의 경우 상관 된 하위 쿼리를 피하려고합니다. 하위 쿼리 내에 외부 쿼리의 열에 대한 참조가있는 경우 하위 쿼리는 상관됩니다. 이 경우 하위 쿼리는 반환 된 모든 행에 대해 한 번 이상 실행되며 상관 된 하위 쿼리가 포함 된 조건이 적용된 후 다른 조건이 적용되면 더 많은 시간이 실행될 수 있습니다.

고려 된 예와 Oracle 구문을 용서하십시오. 그러나 마지막으로 상점에서 하루에 $ 10,000 미만의 판매를 한 이후로 상점에서 고용 된 모든 직원을 찾고 싶다고 가정하십시오.

select e.first_name, e.last_name
from employee e
where e.start_date > 
        (select max(ds.transaction_date)
         from daily_sales ds
         where ds.store_id = e.store_id and
               ds.total < 10000)

이 예제의 하위 쿼리는 store_id의 외부 쿼리와 상관 관계가 있으며 시스템의 모든 직원에 대해 실행됩니다. 이 쿼리를 최적화 할 수있는 한 가지 방법은 하위 쿼리를 인라인보기로 옮기는 것입니다.

select e.first_name, e.last_name
from employee e,
     (select ds.store_id,
             max(s.transaction_date) transaction_date
      from daily_sales ds
      where ds.total < 10000
      group by s.store_id) dsx
where e.store_id = dsx.store_id and
      e.start_date > dsx.transaction_date

이 예제에서 from 절의 쿼리는 이제 인라인 뷰 (일부 Oracle 특정 구문)이며 한 번만 실행됩니다. 데이터 모델에 따라이 쿼리는 훨씬 빠르게 실행될 것입니다. 직원 수가 증가함에 따라 첫 번째 쿼리보다 성능이 우수합니다. 첫 번째 조회는 실제로 직원 수가 적고 상점이 많으며 (아마도 많은 상점에 직원이없는 경우) daily_sales 테이블이 store_id에 색인화되어 있으면 실제로 더 잘 수행 할 수 있습니다. 이것은 가능한 시나리오는 아니지만 상관 된 쿼리가 다른 쿼리보다 성능이 더 우수한 방법을 보여줍니다.

주니어 개발자가 하위 쿼리를 여러 번 연관시키는 것을 보았으며 일반적으로 성능에 심각한 영향을 미쳤습니다. 그러나 상관 부속 조회를 제거 할 때 성능을 악화시키지 않는지 확인하기 전후에 Explain 계획 을 확인하십시오.


1
요점을 강조하고 관련 요점 중 하나를 강조하려면 변경 사항을 테스트하십시오. Explain Plan을 사용하고 (데이터베이스가 실제로 쿼리를 실행하기 위해 수행하는 작업과 비용을 확인), 대규모 데이터 세트에서 테스트를 수행하고, SQL을 지나치게 복잡하고 읽을 수 없거나 최적화 할 수없는 상태로 만들지 마십시오. 실제로 실제 성능을 향상 시키지는 않습니다.
Rob Whelan

21

내 경험으로는 :
숙련 된 DBA와 의사 소통하지 않습니다.


17

"실제"데이터베이스 대신 Access 사용. SQL Express , MySQLSQLite 와 같은 작고 무료 인 데이터베이스가 많으 므로 훨씬 잘 작동하고 확장됩니다. 앱은 종종 예기치 않은 방식으로 확장해야합니다.


16

테이블 간의 관계 설정을 잊어 버렸습니다. 현재 고용주에서 처음 일을 시작할 때이 문제를 해결해야했던 것을 기억합니다.


14

데이터를 저장하기 위해 Excel을 사용합니다.

나는 수천 개의 행을 보유하고 여러 워크 시트를 사용하는 회사를 보았습니다 (이전 버전의 Excel에서는 65535의 행 제한으로 인해).


Excel은 보고서, 데이터 표시 및 기타 작업에 적합하지만 데이터베이스로 취급해서는 안됩니다.


14

다음과 같이 추가하고 싶습니다. 고성능 코드보다 "우아한"코드 선호. 데이터베이스에 대해 가장 잘 작동하는 코드는 종종 응용 프로그램 개발자의 눈에 좋지 않습니다.

조기 최적화에 대한 넌센스를 믿습니다. 데이터베이스는 원래 디자인 및 후속 개발에서 성능을 고려해야합니다. 내 생각에 성능은 데이터베이스 디자인의 50 % (40 %는 데이터 무결성 및 마지막 10 %는 보안)입니다. 실제 사용자와 실제 트래픽이 데이터베이스에 배치되면 맨 아래에서 수행하도록 구축되지 않은 데이터베이스는 제대로 수행되지 않습니다. 조기 최적화는 최적화가 아님을 의미하지 않습니다! 그렇다고해서 쉽게 찾을 수 있기 때문에 거의 항상 제대로 수행되지 않는 코드를 작성해야한다는 의미는 아닙니다. 그것은 당신이 필요할 때까지 마지막으로 약간의 성능을 짜낼 필요가 없다는 것을 의미합니다. 데이터베이스에서 더 잘 수행되는 기능에 대해 많은 것이 알려져 있습니다.


2
+1-데이터베이스 프로그래밍에는 기계 구성 요소의 동작 최적화가 포함됩니다. 그러나 Knuth는 조기 최적화는 시간의 약 97 % (또는 그 영향에 대한 단어)의 모든 악의 근원이라고 말합니다. 데이터베이스 디자인은이 점에 대해 실제로 생각해야 할 영역 중 하나입니다.
ConcernedOfTunbridgeWells

2
Ahem ... 당신이 말하는 것은 조기에 최적화되지 않은 것입니다. 데이터베이스 설계 (및 실제로 응용 프로그램 설계)의 시작부터 실제 사용에 대한 일부 고려가 필요합니다. Knuth의 규칙은 실제로 따라야 할 사소한 것이 아닙니다. 왜냐하면 무엇이 조기인지 아닌지 결정해야하기 때문입니다. 실제로 "데이터없이 최적화를 수행하지 마십시오"라는 결론을 내립니다. 이야기하고 있는 초기 성능 관련 결정 에는 데이터 있습니다. 특정 디자인은 향후 성능에 허용 할 수없는 한계를 설정하고이를 계산할 수 있습니다.
Rob Whelan

13

매개 변수화 된 쿼리를 사용하지 않습니다. SQL Injection 을 중지하는 데 매우 편리합니다 .

이것은 다른 답변에서 언급 한 입력 데이터를 위생 처리하지 않는 구체적인 예입니다.


3
살균 입력을 제외하고는 잘못되었습니다. 살균은 위험 할 수있는 곳에 두는 것을 의미합니다. 매개 변수화는 위험 경로에서 완전히 벗어나는 것을 의미합니다.
더스틴

12

개발자가 중첩 된 select 문을 사용하거나 심지어 함수가 쿼리의 "SELECT"부분 내에서 select 문의 결과를 반환 할 때 나는 그것을 싫어합니다.

@adam도 비슷한 문제가 있음에도 불구하고 실제로 다른 곳에서는 이것을 볼 수 없다는 것에 놀랐습니다.

예:

SELECT
    (SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
    ,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
    MyTable c

이 시나리오에서 MyTable이 10000 개의 행을 반환하면 결과는 쿼리마다 20001 개의 쿼리를 실행 한 것과 같습니다. 결과는 각 쿼리 행마다 초기 쿼리와 다른 테이블 각각을 한 번씩 쿼리해야했기 때문입니다.

개발자는 몇 줄의 데이터 만 반환하는 하위 개발 환경에서이 작업을 수행 할 수 있으며 하위 테이블에는 일반적으로 적은 양의 데이터 만 있지만 프로덕션 환경에서는 이러한 종류의 쿼리가 기하 급수적으로 많은 비용이들 수 있습니다 데이터가 테이블에 추가됩니다.

더 좋은 (반드시 완벽한 것은 아님) 예제는 다음과 같습니다

SELECT
     s.SomeValue As FirstVal
    ,o.OtherValue As SecondVal
FROM
    MyTable c
    LEFT JOIN (
        SELECT SomeDate, MAX(SomeValue) as SomeValue
        FROM SomeTable 
        GROUP BY SomeDate
     ) s ON c.Date = s.SomeDate
    LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria

이렇게하면 데이터베이스 최적화 프로그램이 기본 테이블의 각 레코드를 다시 쿼리하지 않고 데이터를 함께 섞을 수 있으며 일반적 으로이 문제가 발생한 코드를 수정해야 할 때 일반적으로 쿼리 속도를 100 % 증가시킵니다. CPU와 메모리 사용량을 동시에 줄이면서


12

SQL 기반 데이터베이스의 경우 :

  1. CLUSTERED INDEXES를 사용하지 않거나 CLUSTER에 잘못된 열을 선택하지 않았습니다.
  2. 부모 / 자식 테이블 관계에서 FOREIGN KEY (INT)에 조인하기 위해 SERIAL (자동 번호) 데이터 유형을 PRIMARY KEY로 사용하지 않습니다.
  3. 많은 레코드가 삽입 또는 삭제 된 경우 테이블에서 통계를 업데이트하지 않습니다.
  4. 많은 행이 삽입 또는 삭제 된 경우 테이블을 재구성 (즉, 언로드, 삭제, 재 작성,로드 및 재 인덱싱)하지 않음 (일부 엔진은 삭제 플래그를 사용하여 삭제 된 행을 테이블에 물리적으로 유지)
  5. 트랜잭션 속도가 높은 대형 테이블에서 FRAGMENT ON EXPRESSION (지원되는 경우)을 활용하지 않습니다.
  6. 열에 대해 잘못된 데이터 유형을 선택했습니다!
  7. 올바른 열 이름을 선택하지 않았습니다.
  8. 테이블 끝에 새 열을 추가하지 않습니다.
  9. 자주 사용하는 쿼리를 지원하기 위해 적절한 인덱스를 생성하지 않습니다.
  10. 가능한 값이 거의없는 열에 인덱스를 만들고 불필요한 인덱스를 만듭니다.
    ... 더 추가됩니다.

1
퀴즈 : 2) 실제로 나쁜 습관입니다. 나는 당신이 얻는 것을 봅니다. 당신은 그 자동 번호에 대한 고유 색인을 원하고 그것을 대리 키로 사용하려고합니다. 그러나 기본 키는 기본 키가 아니기 때문에 자동 번호가 아니어야합니다. 기본 키는 "레코드에 관한 것"입니다 (판매 거래와 같은 것 제외)는 자동 번호가 아니라 고유 비트입니다. 모델링되는 엔터티에 대한 정보
David T. Macknet

기본 및 외래 키에 자동 번호를 사용하는 주된 이유는 다른 열의 변경에 관계없이 부모-자식 조인을 유지할 수 있도록하기위한 것입니다. 고객 이름이나 다른 데이터와 같은 다른 기본 키를 사용하면 위험 할 수 있습니다!
Frank R.

@David : 수정되었습니다! .. 자동 번호를 기본 키로 사용할 필요가 없습니다. 하나는 여전히 부모에 색인이 지정된 직렬 열을 가질 수 있으며 자식에 서로 게이트를 결합하여 관계가 끊어지지 않도록 보장합니다. 행을 찾기위한 의미있는 기본으로 열!
Frank R.

하루가 끝날 때 의미론의 문제이며 ... Microsoft는 기본 키가 의미가 아닌 무의미한 것을 선호합니다. 그 주위의 논쟁은 계속되고 있지만 나는 "의미있는"캠프에 빠진다. :)
David T. Macknet

9
  • 프로덕션 데이터베이스 내에서 일부 문제를 해결하기 전에 백업하지 않습니다.

  • 스토어드 프로 시저의 스토어드 오브젝트 (예 : 테이블, 뷰)에서 DDL 명령 사용

  • 저장 프로 시저 사용에 대한 두려움 또는 ORM 쿼리가 더 효율적이고 사용하기 쉬운 곳이면 어디에서나 ORM 쿼리 사용에 대한 두려움.

  • 데이터베이스 프로파일 러 사용을 무시하면 ORM 쿼리가 최종적으로 변환되는 대상을 정확하게 알 수 있으므로 ORM을 사용하지 않을 때 로직을 확인하거나 디버깅 할 수 있습니다.


8

올바른 수준의 정규화를 수행하지 않습니다 . 데이터가 복제되지 않고 데이터를 필요에 따라 다른 것으로 분할하려고합니다. 또한 성능이 저하 될 정도로 정규화를 따르지 않아야 합니다.


너무 멀어요? 데이터가 중복되지 않으면 어떻게 더 나아갈 수 있습니까?
finnw 2016 년

정규화는 중복 데이터를 제거하고 유연성을 높이고 성능을 낮추고 복잡성을 높이는 균형입니다. 올바른 균형을 찾는 것은 경험이 필요하며 시간이 지남에 따라 변경됩니다. 비정규 화시기에 대한 정보는 en.wikipedia.org/wiki/Database_normalization 을 참조하십시오
Nathan Voxland

8

데이터베이스를 단순한 저장 메커니즘 (예 : 영광스러운 컬렉션 라이브러리)으로 취급하여 응용 프로그램에 종속 (데이터를 공유하는 다른 응용 프로그램 무시)


이에 대한 결론은 너무 많은 쿼리 작업을 속한 데이터베이스에 유지하는 대신 응용 프로그램에 너무 많은 쿼리 작업을 오프로드하는 것입니다. LINQ는 특히 이것에 대해 나쁩니다.
3Dave

8
  • "매우 마술 적이다"또는 " 나의 것이 아니다"와 같은 이유로 최대 절전 모드와 같은 ORM 해제 데이터베이스".
  • Hibernate와 같은 ORM에 너무 많이 의존하고 적절하지 않은 곳에서 구두를 trying 다.

8

1 - 색인이 사용되지 않은 where 절의 값에서 함수를 불필요하게 사용합니다.

예:

where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate

대신에

where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1

그리고 더 적은 범위 : 기능 색인을 필요한 값에 추가하지 마십시오 ...

2- 데이터의 유효성을 보장하기 위해 점검 제한 조건을 추가하지 않습니다. 제약 조건은 쿼리 최적화 프로그램에서 사용할 수 있으며 불변 값을 신뢰할 수 있도록하는 데 도움이됩니다. 그것들을 사용하지 않을 이유가 없습니다.

3- 순수한 게으름 또는 시간 압력으로 테이블에 정규화되지 않은 열 추가 사물은 일반적으로 이런 식으로 설계되지는 않지만이 방식으로 발전합니다. 최종 결과는 미래 진화에서 손실 된 데이터 무결성에 물렸을 때 혼란을 없애려는 수많은 작업입니다.

데이터가없는 테이블은 재 설계하기에 매우 저렴합니다. 무결성이없는 수백만 개의 레코드가있는 테이블. 따라서 열 또는 테이블을 만들 때 올바른 디자인을 수행하면 스페이드에서 상각됩니다.

4- 데이터베이스 자체는 그다지 중요하지 않지만 실제로는 성가시다. SQL의 코드 품질에 신경 쓰지 않습니다. SQL이 텍스트로 표현된다고해서 문자열 조작 알고리즘의 힙에서 논리를 숨기는 것은 괜찮습니다. 동료 프로그래머가 실제로 읽을 수있는 방식으로 텍스트로 SQL을 작성할 수 있습니다.


7

이전에 언급되었지만 indexes, indexes, indexes 입니다. 나는 약간의 프로파일 링 (어떤 테이블이 많은 히트를했는지 확인)을 수행 한 다음 해당 테이블에 인덱스를 추가하여 수정 된 엔터프라이즈 웹 앱의 성능이 저하되는 경우를 많이 보았습니다. 이것은 SQL 작성 지식을 많이 요구하지도 않으며 그 대가는 엄청납니다.

전염병과 같은 데이터 복제를 피하십시오. 일부 사람들은 약간의 중복이 아프지 않으며 성능을 향상시킬 것이라고 주장합니다. DBA조차도 무슨 일이 일어나고 있는지 알 수 없을 때까지 스키마를 Third Normal Form으로 고문해야한다고 말하는 것은 아닙니다. 일련의 이름, 우편 번호 또는 배송 코드를 복제 할 때마다 사본이 서로 동기화되지 않을 수 있습니다. 일어날거야. 그리고 매주 유지 보수 스크립트를 실행할 때 스스로 발 차게됩니다.

마지막으로, 명확하고 일관된 직관적 인 명명 규칙을 사용하십시오. 잘 작성된 코드를 읽을 수있는 것과 마찬가지로 좋은 SQL 스키마 또는 쿼리를 읽을 수 있어야하며 주석 없이도 실제로 수행중인 작업을 알려야 합니다. 6 개월 안에 테이블을 유지 보수해야 할 때 스스로에게 감사 할 것입니다. "SELECT account_number, billing_date FROM national_accounts""SELECT ACCNTNBR, BILLDAT FROM NTNLACCTS"보다 작업하기가 훨씬 쉽습니다.


올바르게 설정하면 그렇지 않지만 많은 사람들이 알레르기가있는 방아쇠를 사용해야합니다.
HLGEM

6

DELETE 쿼리를 실행하기 전에 (특히 프로덕션 데이터베이스에서) 해당 SELECT 쿼리를 실행하지 않습니다!


5

20 년 동안 본 가장 흔한 실수는 미리 계획하지 않은 것입니다. 많은 개발자가 데이터베이스와 테이블을 만든 다음 응용 프로그램을 빌드 할 때 테이블을 지속적으로 수정하고 확장합니다. 최종 결과는 종종 혼란스럽고 비효율적이며 나중에 정리하거나 단순화하기가 어렵습니다.


1
이러한 상황에서 발생하는 공포를 상상할 수 있습니다 ... 스키마없는 데이터베이스는 빠른 프로토 타이핑 및 반복 개발에 훨씬 적합하지만 다른 모든 것과 마찬가지로 이러한 유연성에는 다양한 트레이드 오프가 있습니다.
Zsolt Török 2012 년

4

a) 문자열의 쿼리 값 하드 코딩
b) Windows Forms 응용 프로그램의 "OnButtonPress"작업에 데이터베이스 쿼리 코드 삽입

나는 둘 다 보았다.


4
"Windows Form 응용 프로그램의"OnButtonPress "작업에 DB 쿼리 코드 삽입"여기에 데이터베이스 오류가 있습니까?
재귀

@recursive : 그것은 엄청난 SQL 주입 취약점입니다. 누구나 서버에 임의의 SQL을 보낼 수 있으며 그대로 실행됩니다.
Bill Karwin

@recursive와 동의했습니다. 이들은 실제로 DB 문제와 관련이 없습니다.
p.campbell

b) 아키텍처 실수입니다. 물론 앱에서 직접 쿼리를 코딩하는 것은 좋지 않습니다.
3Dave

4

응용 프로그램에서 데이터베이스 연결을 관리하는 데 충분한주의를 기울이지 않습니다. 그런 다음 응용 프로그램, 컴퓨터, 서버 및 네트워크가 막혔습니다.


4
  1. DBA 및 데이터 모델러 / 디자이너라고 생각하면 해당 영역에서 어떤 종류의 공식적인 교리가없는 경우.

  2. 그들의 프로젝트에는 DBA가 필요하지 않다고 생각하기 때문에 모든 것이 쉽지 않습니다.

  3. 데이터베이스에서 수행해야하는 작업과 앱에서 수행해야하는 작업을 올바르게 식별하지 못했습니다.

  4. 백업의 유효성을 검사하지 않거나 백업하지 않습니다.

  5. 코드에 원시 SQL을 포함시킵니다.



3

데이터베이스 동시성 모델과 이것이 개발에 미치는 영향을 이해하지 못합니다. 사실 후에는 색인을 추가하고 쿼리를 쉽게 조정할 수 있습니다. 그러나 핫스팟, 리소스 경합 및 올바른 작업 (방금 읽은 내용이 여전히 유효하다고 가정)을 적절히 고려하지 않고 설계된 응용 프로그램은 나중에 수정하기 위해 데이터베이스 및 응용 프로그램 계층 내에서 중요한 변경이 필요할 수 있습니다.


3

DBMS가 어떻게 작동하는지 이해하지 못합니다.

클러치의 작동 방식을 이해하지 않으면 스틱을 올바르게 구동 할 수 없습니다. 그리고 실제로 하드 디스크의 파일에 쓰고 있다는 것을 이해하지 않고는 데이터베이스를 사용하는 방법을 이해할 수 없습니다.

구체적으로 특별히:

  1. 클러스터형 인덱스가 무엇인지 알고 있습니까? 스키마를 설계 할 때 생각해 보셨습니까?

  2. 인덱스를 올바르게 사용하는 방법을 알고 있습니까? 인덱스를 재사용하는 방법? 취재 지수가 무엇인지 아십니까?

  3. 아주 훌륭합니다. 색인이 있습니다. 색인에서 1 행이 얼마나 큽니까? 데이터가 많을 때 인덱스가 얼마나 커 집니까? 메모리에 쉽게 맞습니까? 그렇지 않으면 인덱스로 쓸모가 없습니다.

  4. MySQL에서 EXPLAIN을 사용한 적이 있습니까? 큰. 이제 자신에게 정직하십시오 : 당신이 본 것의 절반을 이해 했습니까? 아니, 아마 그렇지 않았을 것입니다. 고치세요.

  5. 쿼리 캐시를 이해하십니까? 쿼리를 캐싱 할 수 없게 만드는 이유를 알고 있습니까?

  6. MyISAM을 사용하고 있습니까? 전체 텍스트 검색이 필요한 경우 MyISAM은 아무 문제가 없습니다. 스핑크스를 사용하십시오. 그런 다음 Inno로 전환하십시오.


2
더 나은 비유 는 클러치를 이해하지 않고 수동 변속기를 올바르게 해결할 수 없다는 것 입니다. 많은 사람들이 클러치가 어떻게 작동하는지 모르면서 스틱 시프트를 올바르게 운전합니다.
Michael Easter

3
  1. ORM을 사용하여 대량 업데이트 수행
  2. 필요한 것보다 많은 데이터를 선택합니다. 다시 말하지만, 일반적으로 ORM을 사용할 때 수행됩니다.
  3. 루프에서 SQL 실행
  4. 테스트 데이터가 양호하지 않고 라이브 데이터에서만 성능 저하가 눈에.니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.