>  기사  >  데이터 베이스  >  MySQL 열거형 인스턴스 테스트

MySQL 열거형 인스턴스 테스트

小云云
小云云원래의
2017-11-30 11:05:371603검색

열거형이란 무엇인가요? enum은 E.164 Number URI Mapping의 약어입니다. 이 약어 뒤에는 훌륭한 아이디어가 숨어 있습니다. 즉, 가장 좋고 가장 저렴한 라우팅을 통해 전 세계 어디에서나 동일한 전화번호를 사용할 수 있다는 것입니다. 도메인 이름과 마찬가지로 ENUM 번호를 등록할 수 있습니다.

프로젝트를 개발할 때 일반적으로 주문 보류 중인 결제 상태, 지불됨, 마감됨, 환불됨 등과 같은 일부 상태 필드를 접하게 됩니다. 이전에 작업한 프로젝트에서는 이러한 상태가 데이터베이스에 숫자로 저장되어 있었고, 그런 다음 PHP에서 매핑 테이블을 유지하기 위해 코드에서 상수를 사용합니다. 예:

const STATUS_PENDING = 0;
const STATUS_PAID = 1;
const STATUS_CLOSED = 2;
const STATUS_REFUNDED = 3;

그러나 실제 사용에서는 다양한 이유(버그 추적, 임시 통계 요구 사항 등)로 인해 사용하기가 쉽지 않은 것으로 나타났습니다. ) 종종 mysql 서버에 로그인해야 합니다. 일부 SQL을 수동으로 실행해야 합니다. 쿼리는 많은 테이블에 상태 필드가 있으므로 PHP 코드의 매핑 관계에 따라 SQL을 작성해야 합니다. 주의하지 않으면 서로 다른 테이블의 상태 번호를 혼동하여 큰 문제가 발생할 수 있습니다.

그래서 새 프로젝트에서 다양한 상태를 저장하기 위해 mysql의 enum 타입을 사용하려고 했는데요. 열거형 테이블을 변경하면(비열거형 필드를 변경하더라도) 오류가 발생합니다. value 전체 테이블을 다시 작성해야 하며, 데이터 양이 많을 경우 몇 시간이 걸릴 수 있습니다.

enum 값은 리터럴 값의 크기가 아닌 테이블 구조를 생성할 때 지정한 순서대로 정렬됩니다.


enum 값을 확인하기 위해 mysql에 의존할 필요는 없습니다. 기본 구성에 잘못된 값을 삽입하면 결국 null 값이 됩니다.


새 프로젝트의 실제 상황에 따라 상태 필드를 정렬할 필요는 없을 것 같습니다. 있더라도 테이블 구조를 설계할 때 순서를 설정할 수 있으므로 단점 2는 무시할 수 있습니다. ; 그리고 단점 3 코드 사양, 삽입/업데이트 전 확인 등을 통해 피할 수 있습니다. 단점 1의 경우 몇 가지 테스트를 수행해야 합니다.


테스트 준비#

먼저 테이블을 생성하세요:

[Doctrine\DBAL\DBALException]
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.

그런 다음 100W의 데이터를 삽입하세요:

CREATE TABLE `enum_tests` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `status` enum('pending','success','closed') COLLATE utf8mb4_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

테스트 프로세스#

테스트 1#

열거형 값 목록 끝에 환불된 값을 추가하세요

$count = 1000000;
$bulk = 1000;
$data = [];
foreach (['pending', 'success', 'closed'] as $status) {
  $data[$status] = [];
  for ($i = 0; $i < $bulk; $i++) {
    $data[$status][] = [&#39;status&#39; => $status];
  }
}
  
for ($i = 0; $i < $count; $i += $bulk) {
  $status = array_random([&#39;pending&#39;, &#39;success&#39;, &#39;closed&#39;]);
  EnumTest::insert($data[$status]);

출력 :

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;closed&#39;,&#39;refunded&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

결론: 마지막에 enum 값을 추가하면 비용이 거의 들지 않습니다.


테스트 2: #

방금 추가한 값을 삭제합니다. 여전히 허용 가능한 범위 내에 있습니다.

테스트 3: #

Refunded를 값 목록 끝 부분이 아닌 중간에 삽입

Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0


출력:

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;closed&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

결론: 값 목록 중간에 새 값 추가 원래 열거형 값 목록에는 전체 테이블 스캔이 필요하며 업데이트 비용이 더 많이 듭니다.

테스트 4: #

값 목록 중간에 있는 값 삭제

Query OK, 1000000 rows affected (5.93 sec)
Records: 1000000 Duplicates: 0 Warnings: 0

출력:

ALTER TABLE `enum_tests` CHANGE `status` `status` ENUM(&#39;pending&#39;,&#39;success&#39;,&#39;refunded&#39;, &#39;closed&#39;) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

결론: 전체 테이블 스캔이 필요하며 비용이 높습니다.

테스트 5: #

상태 필드에 인덱스를 추가한 후 위의 테스트를 실행합니다

Query OK, 1000000 rows affected (6.00 sec)
Records: 1000000 Duplicates: 0 Warnings: 0


테스트 2~4의 시간 소모가 늘어난 것으로 나타났습니다. 동시에 인덱스를 업데이트합니다.

결론: #

새 프로젝트에서는 새로운 enum 값만 나타날 것입니다. 앞으로 일부 상태가 폐기되더라도 enum 값 목록을 조정할 필요가 없으므로 enum을 도입하기로 결정했습니다. 프로젝트. Type은 상태를 저장하기 위한 데이터 유형 역할을 합니다.

관련 권장사항:

php의 Enum(열거) 사용법에 대한 자세한 설명


Enum 확장 기능 예제 코드

enum 데이터 유형의 기본값에 대한 혼란 해결 방법

위 내용은 MySQL 열거형 인스턴스 테스트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.