web-dev-qa-db-fra.com

Changer la clé primaire en incrémentation automatique

J'ai un joueur de table, et un playerID de clé primaire qui est le caractère (7). J'ai déjà des enregistrements dans cette table, et j'ai également d'autres tables qui ont playerID comme clé étrangère, et ces tables ont également déjà des enregistrements.

Comment puis-je définir le playerID pour incrémenter automatiquement? Après avoir lu pendant un certain temps, je pense que j'aurais dû le faire depuis le début, mais comme je ne peux pas le faire maintenant, est-ce que je peux le faire de toute façon?

Par exemple, lorsque je lance cette

ALTER TABLE player ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

il renvoie une erreur:

ERROR: multiple primary keys for table "player" are not allowed

et si je supprime le playerID existant, les enregistrements dans d'autres tables qui y font référence seront également supprimés.

Existe-t-il un moyen de "changer" la clé primaire playerID existante pour incrémenter automatiquement?

23
Chin

Je le comprends: il suffit d'ajouter une valeur par défaut d'incrémentation automatique au playerID:

create sequence player_id_seq;
alter table player alter playerid set default nextval('player_id_seq');
Select setval('player_id_seq', 2000051 ); --set to the highest current value of playerID
52
Chin
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

   -- create som data to play with
CREATE TABLE bagger
        ( player_id CHAR(6)
        , tralala varchar
        );

  -- populate the table
INSERT INTO bagger(player_id,tralala)
SELECT gs::text, 'zzz_' || gs::text
FROM generate_series(1,10) gs
        ;

SELECT * FROM bagger;

  --
  -- create the sequence, change the datatype and bind it to the sequence
  --
CREATE SEQUENCE player_id_seq;
ALTER TABLE bagger
        ALTER COLUMN player_id TYPE INTEGER USING player_id::integer
        , ALTER COLUMN player_id SET NOT NULL
        , ALTER COLUMN player_id SET DEFAULT nextval('player_id_seq')
        ;
ALTER SEQUENCE player_id_seq
        OWNED BY bagger.player_id
        ;
   --
   -- reset the sequence to containe the maximum occuring player_id in the table
   --
SELECT setval('player_id_seq', mx.mx)
FROM (SELECT MAX(player_id) AS mx FROM bagger) mx
        ;
SELECT * FROM bagger;
\d bagger

Production:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 10
 player_id | tralala 
-----------+---------
 1         | zzz_1
 2         | zzz_2
 3         | zzz_3
 4         | zzz_4
 5         | zzz_5
 6         | zzz_6
 7         | zzz_7
 8         | zzz_8
 9         | zzz_9
 10        | zzz_10
(10 rows)

CREATE SEQUENCE
ALTER TABLE

 setval 
--------
     10
(1 row)

 player_id | tralala 
-----------+---------
         1 | zzz_1
         2 | zzz_2
         3 | zzz_3
         4 | zzz_4
         5 | zzz_5
         6 | zzz_6
         7 | zzz_7
         8 | zzz_8
         9 | zzz_9
        10 | zzz_10
(10 rows)

                                 Table "tmp.bagger"
  Column   |       Type        |                      Modifiers                      
-----------+-------------------+-----------------------------------------------------
 player_id | integer           | not null default nextval('player_id_seq'::regclass)
 tralala   | character varying | 
5
wildplasser

Je ne pense pas que vous pouvez avoir 2 clés primaires dans une table, et parce que le type de données playerID est caractère (7), je ne pense pas que vous pouvez le changer en incrémentation automatique.

Je pense donc que vous devrez supprimer la contrainte de clé primaire sur playerID si vous voulez pouvoir ajouter une nouvelle clé primaire.

Puisque vous avez déjà des données sur votre table et que vous utilisez playerID comme clé étrangère dans d'autres tables, je vous conseille de dupliquer votre table de joueur et de tester ces modifications sur votre deuxième table pour éviter de corrompre vos données.

Mais avant d'essayer tout cela, assurez-vous que vous essayez d'effectuer ces modifications en utilisant le même utilisateur db qui a créé les tables que vous modifiez

1
Ferox