문제

우리는 InnoDB 저장 엔진과 트랜잭션과 함께 MySQL을 많이 사용하고 있으며 문제가 발생했습니다. MySQL에서 Oracle의 시퀀스를 모방하는 좋은 방법이 필요합니다. 요구 사항은 다음과 같습니다 .- 동시성 지원 - 거래 안전 - 최대 성능 (자물쇠 및 교착 상태 최소화)

우리는 일부 값이 사용되지 않는지 상관하지 않습니다. 즉, 순서대로 간격은 괜찮습니다. 카운터가있는 별도의 innodb 테이블을 만들어서 쉽게 아치하는 방법이 있지만, 이는 트랜잭션에 참여하고 자물쇠와 대기를 소개한다는 것을 의미합니다. 수동 잠금 장치, 다른 아이디어 또는 모범 사례가있는 MyISAM 테이블을 시험해 볼 생각이 있습니까?

도움이 되었습니까?

해결책

자동 점수가 귀하의 요구에 충분하지 않으면 원자 시퀀스 메커니즘을 만들 수 있습니다. N 다음과 같은 이름의 시퀀스 :

시퀀스를 저장할 테이블을 만듭니다.

CREATE TABLE sequence (
  seq_name varchar(20) unique not null,
  seq_current unsigned int not null
);

테이블에 'foo'행이 있다고 가정하면 다음 시퀀스 ID를 원자 적으로 얻을 수 있습니다.

UPDATE sequence SET seq_current = (@next := seq_current + 1) WHERE seq_name = 'foo';
SELECT @next;

자물쇠가 필요하지 않습니다. 동일한 세션에서 두 문장을 실행해야하므로 로컬 변수 @Next가 실제로 선택된 경우 정의됩니다.

다른 팁

이것을하는 올바른 방법은 MySQL 매뉴얼:

UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();

우리는 높은 거래 게임 회사이며 우리의 요구에 대한 이러한 종류의 솔루션이 필요합니다. Oracle 시퀀스의 특징 중 하나는 또한 설정할 수있는 증분 값이었습니다.

솔루션이 사용됩니다 DUPLICATE KEY.

CREATE TABLE sequences (
  id BIGINT DEFAULT 1,
  name CHAR(20),
  increment TINYINT,
  UNIQUE KEY(name)
);

다음 색인을 얻으려면 :

저장된 절차 또는 기능으로 다음을 추상화하십시오. sp_seq_next_val(VARCHAR):

INSERT INTO sequences (name) VALUES ("user_id") ON DUPLICATE KEY UPDATE id = id + increment;<br/>
SELECT id FROM sequences WHERE name = "user_id";

Won't the MySQL Identity column on the table handle this?

CREATE TABLE table_name ( id INTEGER AUTO_INCREMENT PRIMARY KEY )

Or are you looking to use it for something other than just inserting into another table?

If you're writing using a procedural language as well (instead of just SQL) then the other option would be to create a table containing a single integer (or long integer) value and a stored procedure which locked it, selected from it, incremented it and unlocked it before returning the value.

(Note - always increment before you return the value - it maximise the chance of not getting duplicates if there are errors - or wrap the whole thing in a transaction.)

You would then call this independently of your main insert / update (so it doesn't get caught in any transactions automatically created by the calling mechanism) and then pass it as a parameter to wherever you want to use it.

Because it's independent of the rest of the stuff you're doing it should be quick and avoid locking issues. Even if you did see an error caused by locking (unlikely unless you're overloading the database) you could just call it a second / third time.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top