4 MySQL 트랩
Originally posted at michaelzanggl.com. Subscribe to my newsletter to never miss out on new content.
참고: 이들 중 일부는 다른 데이터베이스 시스템에도 존재할 수 있습니다.
utf8은 실제로 utf8이 아닙니다.
이 SQL 예외가 발생한 적이 있습니까?
Incorrect string value: ‘\xF0\x9F\x98\x83 <…’ for column...
당신은 아마도 다른 많은 사람들과 같은 함정에 빠졌을 것입니다. mySQL의 utf8 charset은 가능한 모든 유니코드 코드 포인트의 약 6%만 저장할 수 있습니다. 예를 들어 이모티콘도 제외됩니다.
insert into emails(body) values ('🦄🦄🦄');
그렇기 때문에
utf8mb4
를 대신 사용해야 합니다.자세한 내용 및 마이그레이션 방법: https://mathiasbynens.be/notes/mysql-utf8mb4
varchar_field를 false 또는 0과 비교
다음과 같은 고안된 예를 상상해보십시오.
function normalizeEmail(email) {
if (!validate(email)) {
return false
}
return normalize(email)
}
// somewhere in the code
await User.where('email', normalizeEmail(email)).first()
가상의 ORM은 쿼리를 실행합니다
select * from users where email = <prepared value> LIMIT 1
.normalizeEmail
내부의 유효성 검사가 성공한 경우 쿼리는 select * from users where email = '[email protected]' LIMIT 1
가 됩니다.유효성 검사가 성공하지 못한 경우 쿼리는
select * from users where email = false LIMIT 1
가 됩니다.이제 데이터베이스 시스템에서
select * from users where <varchar field> = false
와 같은 것을 실행하십시오.필드가 비교할 수 없기 때문에 MySQL은 하나를 다른 것으로 변환하고 일치하게 만들고 모든 사용자를 반환합니다. 우리의 ORM은 단순히 첫 번째 사용자를 선택하고 그것으로 논리를 계속할 것입니다. 😬 꽤 위험하다.
The same happens with
field = 0
중복 키 업데이트에 삽입하면 기본 키 구멍이 생성됩니다.
statistics
(AI), id
, fkid
열이 있는 테이블title
이 있다고 상상해보십시오.INSERT INTO statistics (fkid, title) VALUES (1, 'first');
이렇게 하면
id
1이 있는 새 레코드가 삽입됩니다. 항상 제목을 삽입하거나 업데이트하는 배치가 있다고 가정해 보겠습니다. 일정 시간 동안 다음 쿼리를 실행할 수 있습니다.INSERT INTO statistics (fkid, title) VALUES (1, 'second') ON DUPLICATE KEY UPDATE title = 'second';
INSERT INTO statistics (fkid, title) VALUES (1, 'third') ON DUPLICATE KEY UPDATE title = 'third';
INSERT INTO statistics (fkid, title) VALUES (1, 'fourth') ON DUPLICATE KEY UPDATE title = 'fourth';
마지막으로 새 fkid가 있는 레코드를 삽입하려고 합니다.
INSERT INTO statistics (fkid, title) VALUES (100, 'first') ON DUPLICATE KEY UPDATE title = 'first';
이것은 테이블에 새 레코드를 삽입하지만
id
가 무엇인지 추측합니까? 2가 될 것으로 예상할 수 있지만 실제로 insert on duplicate key update
가 update
를 삽입하고 처리하는 데 실패할 때마다 내부적으로 자동 증분을 증가시켰습니다. 즉, 이 레코드의 id
는 5가 됩니다.ID가 실제로 순차적인 것은 그다지 중요하지 않지만 그 원인이 무엇인지 궁금할 수 있습니다.
자세히 알아보기: https://stackoverflow.com/questions/38347110/prevent-innodb-auto-increment-on-duplicate-key
int(2)는 당신이 생각하는 것과 다릅니다.
INT의 길이는 MySQL에서 실제 의미가 없습니다. 여전히 9999999와 같은 값을 삽입할 수 있습니다. 명령줄 클라이언트에 표시되어야 하는 문자 수만 제한합니다. 🤨
자세히 알아보기: https://stackoverflow.com/questions/5634104/what-is-the-size-of-column-of-int11-in-mysql-in-bytes
당신이 알고 있는 다른 함정이 있습니까?
Reference
이 문제에 관하여(4 MySQL 트랩), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/michi/4-mysql-traps-1oa1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)