2011-01-12 8 views
3

私は企業とその製品のデータベースを持っていますが、それぞれ の会社が別々の製品IDシーケンスを持つことを望みます。postgresql社のIDベースのシーケンス

私はpostgresqlがこれを行うことができないことを知っていますが、唯一の方法は各会社に別々のシーケンスを持たせることですが、これは面倒です。

私は

などの製品、カテゴリとして、「テーブル」は、シーケンスのテーブル名ホルトになりますシーケンス

CREATE TABLE "sequence" 
(
    "table" character varying(25), 
    company_id integer DEFAULT 0, 
    "value" integer 
) 

を保持するために別のテーブルを持っている解決策について考えと値は挿入時にproduct_idに使用される実際のシーケンスデータを保持します

私はUPDATE ... RETURNING値を使用します。製品IDを取得する

このソリューションは効率的ですか?

行レベルのロックでは、同じ会社のユーザーが同じテーブルに行を追加するだけでロックを取得する必要があり、競合状態の問題が軽減されると思います。

この問題を解決するには、より良い方法がありますか?

私は製品IDの違いが大きいので、すべての企業の製品テーブルのシーケンスを使用したくない、私はユーザーのために簡単にしたい。

答えて

3
あなたは自分の会社テーブル内のカウンタを埋め込むことができ

CREATE TABLE companies (
    id   SERIAL PRIMARY KEY, 
    name  TEXT, 
    product_id INT DEFAULT 0 
); 

CREATE TABLE products (
    company  INT REFERENCES companies(id), 
    product_id INT, 
    PRIMARY KEY (company, product_id), 

    name  TEXT 
); 

INSERT INTO companies (id, name) VALUES (1, 'Acme Corporation'); 
INSERT INTO companies (id, name) VALUES (2, 'Umbrella Corporation'); 

次に、利用UPDATE ...与えられた会社のために次のプロダクトIDを取得するためにRETURNING:

> INSERT INTO products VALUES (1, (UPDATE companies SET product_id = product_id+1 WHERE id=$1 RETURNING product_id), 'Anvil'); 
ERROR: syntax error at or near "companies" 
LINE 1: INSERT INTO products VALUES (1, (UPDATE companies SET produc... 
              ^

ああのNOE ! PostgreSQL 9.1以降ではUPDATE ... RETURNINGをサブクエリとして使用できないようです。

良いニュースは、問題ではありません!

CREATE FUNCTION next_product_id(company INT) RETURNS INT 
AS $$ 
    UPDATE companies SET product_id = product_id+1 WHERE id=$1 RETURNING product_id 
$$ LANGUAGE 'sql'; 

今すぐ挿入がケーキの一部です:

INSERT INTO products VALUES (1, next_product_id(1), 'Anvil'); 
INSERT INTO products VALUES (1, next_product_id(1), 'Dynamite'); 
INSERT INTO products VALUES (2, next_product_id(2), 'Umbrella'); 
INSERT INTO products VALUES (1, next_product_id(1), 'Explosive tennis balls'); 

は、製品の価値との両方で同じ会社のIDを使用してくださいだけインクリメント/パートを返すんストアドプロシージャを作成します引数はnext_product_id(company INT)です。

+0

これは私の知る限り、atomic:companies.product_idが製品に対応する挿入なしで増分される可能性があることに注意してください。 –

+0

また、現在のバージョンのPostgreSQLでは、ストアドプロシージャは必要ないかもしれません。 –

0

あなたは会社の数に応じて、各会社のシーケンスを作成できます。 product_id列にデフォルトとして設定されている関数でクエリを実行します。

また、この関数は単にSELECT FOR UPDATEを実行してテーブルの値を更新することもできます。私はかなり演技するべきだと思います。

関連する問題