기본 SQL Debugging

쿼리 설계

다음과 같은 몇 가지 규칙을 따르면 쿼리에서 오류를 훨씬 쉽게 찾을 수 있으며, 특히 SQL은 알지만 특정 스키마에 대해서는 전혀 모르는 사람에게 도움을 요청할 때 더욱 그렇습니다. 읽기 쉬운 쿼리는 디버깅하기 쉬운 쿼리입니다. 쿼리 내에서 절을 그룹화하려면 공백을 사용하세요. 테이블과 필드 별칭을 선택할 때는 혼란스럽지 않고 명확하도록 하세요. 쿼리의 의미를 나타내는 구문을 선택하세요.

공백 사용

읽기 어려운 쿼리는 디버깅하기 어려운 쿼리입니다. 공백은 무료입니다. 새로운 줄과 들여쓰기는 쿼리를 읽기 쉽게 만들어 주며, 특히 스크립팅 언어 내에서 쿼리를 구성할 때 변수가 쿼리 전반에 걸쳐 배치되는 경우에 그렇습니다.

다음에는 구문 오류가 있습니다. 얼마나 빨리 찾을 수 있나요?

SELECT u.id, u.name, alliance.ally FROM users u JOIN alliance ON
(u.id=alliance.userId) JOIN team ON (alliance.teamId=team.teamId
WHERE team.teamName='Legionnaires' AND u.online=1 AND ((u.subscription='paid'
AND u.paymentStatus='current') OR u.subscription='free') ORDER BY u.name;

다음은 공백을 올바르게 사용한 동일한 쿼리입니다. 오류를 더 빨리 찾을 수 있나요?

SELECT
    u.id
    , u.name
    , alliance.ally
FROM
    users u
    JOIN alliance ON (u.id = alliance.userId)
    JOIN team ON (alliance.teamId = team.teamId
WHERE
    team.teamName = 'Legionnaires'
    AND u.online = 1
    AND (
        (u.subscription = 'paid' AND u.paymentStatus = 'current')
        OR
        u.subscription = 'free'
    )
ORDER BY
    u.name;

SQL을 모르더라도 team.teamId 뒤에 ')'가 누락된 것을 발견했을 수도 있습니다.

사용하는 정확한 형식 스타일은 그다지 중요하지 않습니다. select 목록에서 표현식을 따라오는 쉼표를 선호할 수도 있고, 그보다는 앞에 오도록 할 수도 있습니다. 탭이나 공백으로 들여쓰기를 할 수 있습니다. 특정 형식을 고수하는 것은 중요하지 않습니다. 가독성만이 유일한 목표입니다.

테이블 및 필드 별칭

별칭을 사용하면 쿼리 내에서 사용할 테이블과 필드의 이름을 바꿀 수 있습니다. 원래 이름이 매우 긴 경우 유용할 수 있으며, 셀프 조인 및 특정 서브쿼리에 필수적입니다. 그러나 별칭을 잘못 선택하면 쿼리를 더 쉽게 디버깅하기는커녕 더 어렵게 만들 수 있습니다. 별칭은 임의의 문자열이 아니라 원래 테이블 이름을 반영해야 합니다.

잘못된 예:

SELECT *
FROM
    financial_reportQ_1 AS a
    JOIN sales_renderings AS b ON (a.salesGroup = b.groupId)
    JOIN sales_agents AS c ON (b.groupId = c.group)
WHERE
    b.totalSales > 10000
    AND c.id != a.clientId

조인된 테이블 목록과 WHERE 절이 늘어남에 따라, 주어진 별칭이 어떤 테이블을 가리키는지 확인하기 위해 쿼리의 맨 위를 반복해서 살펴봐야 합니다.

더 좋은 방법:

SELECT *
FROM
    financial_report_Q_1 AS frq1
    JOIN sales_renderings AS sr ON (frq1.salesGroup = sr.groupId)
    JOIN sales_agents AS sa ON (sr.groupId = sa.group)
WHERE
    sr.totalSales > 10000
    AND sa.id != frq1.clientId

각 별칭은 조금 더 길지만, 테이블 이니셜은 데이터베이스에 익숙한 사람이라면 전체 테이블 이름을 한 번만 보고도 쿼리의 나머지 부분을 읽으면서 어떤 테이블이 어떤 별칭과 연결되는지 대체로 기억할 수 있을 만큼 충분한 단서를 제공합니다.

JOIN 조건 배치

매뉴얼에서는 행을 제한하는 목적으로 JOIN 조건(즉, ON 절)을 사용하지 않도록 경고하고 있습니다. 특히 암시적 조인을 사용하는 몇몇 쿼리는 모든 조인 조건이 WHERE 절로 이동하는 정반대의 극단적인 방식을 취합니다. 결과적으로 테이블 관계가 비즈니스 로직과 혼합됩니다.

잘못된 예:

SELECT *
FROM
    family,
    relationships
WHERE
    family.personId = relationships.personId
    AND relationships.relation = 'father'

WHERE 절을 자세히 살펴보지 않으면 두 테이블을 연결하는 것이 무엇인지 알 수 없습니다.

더 좋은 방법:

SELECT *
FROM
    family
    JOIN relationships ON (family.personId = relationships.personId)
WHERE
    relationships.relation = 'father'

테이블 간의 관계가 바로 명확해집니다. WHERE 절은 결과 셋의 행을 제한하는 데 사용됩니다.

이러한 제한을 준수하면 쉼표 연산자를 사용하여 테이블을 조인할 수 없습니다. 이는 작은 대가를 치르는 것입니다. 어쨌든 쿼리는 명시적인 JOIN 키워드를 사용하여 작성해야 하며, 새 버전에서 연산자 우선순위가 변경될 때마다 모든 쿼리를 다시 작성하고 싶지 않다면 이 두 가지를 혼용해서는 안 됩니다.

구문 오류 찾기

구문 오류는 가장 쉽게 해결할 수 있는 문제 중 하나입니다. MariaDB는 파서가 혼란스러워진 정확한 지점을 보여 주는 오류 메시지를 제공합니다. 오류 메시지에 표시된 구문 앞의 몇 단어를 포함하여 쿼리를 확인하세요. 대부분의 구문 및 구문 분석 오류는 다시 살펴보면 확실해지지만, 오류 텍스트가 비어 있거나 유효한 키워드를 가리키거나 완전히 올바른 구문에서 오류가 발생한 것처럼 보이는 경우 등 좀 더 파악하기 어려운 경우도 있습니다.

빈 오류 해석하기

대부분의 구문 오류는 해석하기 쉽습니다. 오류는 일반적으로 문제의 정확한 원인을 자세히 설명합니다. 오류 메시지를 염두에 두고 쿼리를 주의 깊게 살펴보면 철자가 틀린 필드 이름, 누락된 'AND', 추가된 닫는 괄호 등 명백한 실수를 발견할 수 있는 경우가 많습니다. 때로는 오류 메시지가 도움이 되지 않는 경우도 있습니다.

자주 발생하지만 도움이 되지 않는 메시지:

ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near ' ' at line 1

빈 ' ' 오류 메시지 때문에 실망할 수 있습니다. 분명히 오류가 있는데, 어디에 있을까요? 확인해야 할 가장 좋은 곳은 쿼리 끝 부분입니다. ' ' 는 파서가 구문 토큰이 나타날 것으로 예상하면서 구문의 끝에 도달했음을 나타냅니다.

' 및 )와 같이 누락된 닫는 문자가 있는지 확인하세요.

SELECT * FROM someTable WHERE field = 'value

노출된 쉼표로 표시되는 경우 불완전한 절을 찾아보세요.

SELECT * FROM someTable WHERE field = 1 GROUP BY id,

키워드 확인

MariaDB는 테이블 및 필드 이름과 별칭으로 예약어도 허용합니다. 모호성을 방지하기 위해 이러한 이름은 백틱(`)으로 묶어야 합니다.

SELECT * FROM actionTable WHERE `DELETE` = 1;

구문 오류가 식별자 중 하나 근처에 표시되는 경우 예약어 목록에 나타나는지 확인하세요.

SQL 구문에 대한 색상 하이라이팅 기능이 있는 텍스트 편집기를 사용하면 이러한 오류를 찾는 데 도움이 됩니다. 필드 이름을 입력했는데 SELECT 키워드와 같은 색으로 표시되면 뭔가 잘못되었다는 뜻입니다.

일부 흔한 문제의 원인들:

  • DESC는 "description" 필드의 일반적인 약어입니다. MariaDB ORDER 절에서는 "내림차순"을 의미합니다.
  • DATE, TIME, TIMESTAMP는 모두 일반적인 필드 이름입니다. 필드 유형이기도 합니다.
  • ORDER는 판매 애플리케이션에 나타납니다. MariaDB에서는 결과 정렬을 지정하는 데 사용됩니다.

일부 키워드는 너무 흔해서 MariaDB에서 따옴표 없이 사용할 수 있도록 특별히 허용됩니다. 제안(원문의 의견): 하지 마세요. 키워드가 있다면 인용하세요.

버전별 구문

MariaDB에 새로운 기능이 추가되면 이를 지원하기 위해 구문도 변경되어야 합니다. 대부분의 경우, 이전 구문은 최신 버전의 MariaDB에서 작동합니다. 한 가지 주목할 만한 예외는 버전 5.0에서 JOIN 키워드와 관련된 쉼표 연산자의 우선 순위가 변경된 것입니다. 이전에는 다음과 같이 작동하던 쿼리가 이제 실패할 것입니다.

SELECT * FROM a, b JOIN c ON a.x = c.x;

그러나 더 일반적인 상황은 오래된 버전에서 새로운 구문을 사용하려고 시도합니다. 웹 호스팅 회사들은 MariaDB 업그레이드가 느리기로 악명이 높기 때문에 몇 년이 지난 버전을 사용하게 될 수도 있습니다. 최근 설치한 자체 워크스테이션에서는 완벽하게 실행되는 쿼리가 제작 환경에서는 실패하면 매우 실망스러울 수 있습니다.

이 쿼리는 서버에 서브쿼리가 추가된 MySQL 4.1 이전의 모든 버전에서 실패합니다.

SELECT * FROM someTable WHERE someId IN (SELECT id FROM someLookupTable);

JOIN 구문이 원래 ON 절을 허용하지 않았기 때문에 일부 초기 버전의 MySQL에서는 이 쿼리가 실패합니다.

SELECT * FROM tableA JOIN tableB ON tableA.x = tableB.y;

항상 설치된 MariaDB 버전을 확인하고 해당 버전과 관련된 매뉴얼의 섹션을 읽어 보세요. 매뉴얼에는 일반적으로 특정 구문을 사용할 수 있게 된 시기가 정확히 명시되어 있습니다.

이 문서의 초기 버전은 다음에서 허가를 받아 복사한 것입니다. http://hashmysql.org/wiki/Basic_Debugging on 2012-10-05.

Comments

Comments loading...
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.