[sql] 가장 일반적인 SQL 안티 패턴은 무엇입니까? [닫은]

관계형 데이터베이스를 다루는 우리 모두는 SQL이 다르다는 것을 배웠습니다. 원하는 결과를 도출하고 효율적으로 수행하려면 익숙하지 않은 패러다임을 배우고 가장 친숙한 프로그래밍 패턴 중 일부가 여기서 작동하지 않는 것을 발견하는 지루한 프로세스가 필요합니다. 당신이 본 (또는 당신이 저지른) 일반적인 반 패턴은 무엇입니까?



답변

데이터 액세스 계층에서 UI 논리를 혼합하려는 대부분의 프로그래머 경향에 대해 일관되게 실망합니다.

SELECT
    FirstName + ' ' + LastName as "Full Name",
    case UserRole
        when 2 then "Admin"
        when 1 then "Moderator"
        else "User"
    end as "User's Role",
    case SignedIn
        when 0 then "Logged in"
        else "Logged out"
    end as "User signed in?",
    Convert(varchar(100), LastSignOn, 101) as "Last Sign On",
    DateDiff('d', LastSignOn, getDate()) as "Days since last sign on",
    AddrLine1 + ' ' + AddrLine2 + ' ' + AddrLine3 + ' ' +
        City + ', ' + State + ' ' + Zip as "Address",
    'XXX-XX-' + Substring(
        Convert(varchar(9), SSN), 6, 4) as "Social Security #"
FROM Users

일반적으로 프로그래머는 데이터 집합을 그리드에 직접 바인딩하려고하기 때문에 클라이언트에서 형식보다 SQL Server 형식의 서버 쪽을 사용하는 것이 편리하기 때문에이 작업을 수행합니다.

위에 표시된 것과 같은 쿼리는 데이터 계층을 UI 계층에 밀접하게 연결하기 때문에 매우 취약합니다. 또한이 프로그래밍 스타일은 저장 프로 시저를 재사용 할 수 없도록 철저히 방지합니다.


답변

여기 내 탑 3이 있습니다.

번호 1. 필드 목록을 지정하지 못했습니다. (편집 : 혼란을 피하기 위해 : 이것은 프로덕션 코드 규칙입니다. 저자가 아닌 한 일회성 분석 스크립트에는 적용되지 않습니다.)

SELECT *
Insert Into blah SELECT *

해야한다

SELECT fieldlist
Insert Into blah (fieldlist) SELECT fieldlist

루프 변수가있는 while 루프가 수행 될 때 커서와 while 루프를 사용합니다.

DECLARE @LoopVar int

SET @LoopVar = (SELECT MIN(TheKey) FROM TheTable)
WHILE @LoopVar is not null
BEGIN
  -- Do Stuff with current value of @LoopVar
  ...
  --Ok, done, now get the next value
  SET @LoopVar = (SELECT MIN(TheKey) FROM TheTable
    WHERE @LoopVar < TheKey)
END

문자열 유형을 통한 DateLogic

--Trim the time
Convert(Convert(theDate, varchar(10), 121), datetime)

해야한다

--Trim the time
DateAdd(dd, DateDiff(dd, 0, theDate), 0)

최근에 “하나의 쿼리가 두 개보다 낫습니다.”라는 급증을 보았습니다.

SELECT *
FROM blah
WHERE (blah.Name = @name OR @name is null)
  AND (blah.Purpose = @Purpose OR @Purpose is null)

이 쿼리에는 매개 변수 값에 따라 두 개 또는 세 개의 다른 실행 계획이 필요합니다. 이 SQL 텍스트에 대해 하나의 실행 계획 만 생성되어 캐시에 고정됩니다. 이 계획은 매개 변수 값에 관계없이 사용됩니다. 결과적으로 간헐적으로 성능이 저하됩니다. 의도 한 실행 계획 당 하나의 쿼리 인 두 개의 쿼리를 작성하는 것이 훨씬 좋습니다.


답변

  • 사람이 읽을 수있는 비밀번호 필드 (예 : ad) 자기 설명.

  • 인덱스
    열에 대해 LIKE를 사용하면 일반적으로 LIKE라고 말하고 싶어합니다.

  • SQL 생성 PK 값을 재활용합니다.

  • 서프라이즈 아무도 언급하지 신 테이블을 아직. 100 열의 비트 플래그, 큰 문자열 및 정수와 같은 “유기적”이란 말은 없습니다.

  • 그런 다음 CSV 파일 , 파이프로 구분 된 문자열 또는 기타 구문 분석이 필요한 데이터를 큰 텍스트 필드에 저장하는 “.ini 파일이 누락되었습니다” 패턴이 있습니다.

  • 그리고 MS SQL 서버의 경우 커서 를 전혀 사용하지 않습니다 . 주어진 커서 작업을 수행하는 더 좋은 방법이 있습니다.

너무 많아 편집했습니다!


답변

깊이 파고들 필요가 없습니다. 준비된 진술을 사용하지 마십시오.


답변

무의미한 테이블 별칭 사용 :

from employee t1,
department t2,
job t3,
...

큰 SQL 문을 읽는 것보다 훨씬 어렵게 만듭니다.


답변

var query = "select COUNT(*) from Users where UserName = '"
            + tbUser.Text
            + "' and Password = '"
            + tbPassword.Text +"'";
  1. 맹목적으로 신뢰하는 사용자 입력
  2. 매개 변수화 된 쿼리를 사용하지 않음
  3. 일반 텍스트 비밀번호

답변

내 버그 베어는 450 명의 열 액세스 테이블로, 상무 이사의 가장 친한 친구 개 그 루머의 8 살짜리 아들과 누군가가 데이터 구조를 올바르게 정규화하는 방법을 모르기 때문에 존재하는 닷지 조회 테이블입니다.

일반적으로이 조회 테이블은 다음과 같습니다.

ID INT,
NVARCHAR (132) 이름,
IntValue1 INT,
IntValue2 INT,
CharValue1 NVARCHAR (255),
CharValue2 NVARCHAR (255),
날짜 1 DATETIME,
날짜 2 DATETIME

나는 이와 같은 가증에 의존하는 시스템을 가지고있는 고객을 보았습니다.