0

I'm facing problems with Primary Key(PK) on my Android x Web Server system, given that the user can create new Objects on the client-side and Off-line. These objects will be sent to server when the user decides to.

This synchronization caused lots of Foreign Key(FK) and PK issues, because my database uses Auto-increment PK.

To solve these integrity issues, after some search, I've decided that the simplest way was to use UUID as my PK in both Android Client and Java Server.

David Bélanger's answer about UUID and index helped a lot.

Now I have 1 question and 1 problem:

  • Question: Is this an acceptable solution to my problem?. If its not.. could give me an alternative? (Realtime database seems to be a hard work to do with my system)

  • Problem: Given that I already have a production database and I can't start over, how can I change the PK from integer unsigned to binary(16).

My final select statement needs to be like that this:

  • select id from table where id = hex('any ID')

Because I'll start inserting data like this:

  • insert into table(id) values (unhex(replace(uuid(), '-', '')));

I tried update id using * unhex(id) * conv(id, 10, 16)

What am I missing?

EDIT: Using thease scripts, I was able to recreate all IDs and Foreign keys

select concat ('alter table ', TABLE_NAME, ' drop foreign key ', CONSTRAINT_NAME, ';') from information_schema.KEY_COLUMN_USAGE where table_schema = 'my_table_name' and CONSTRAINT_NAME like 'fk%'
select concat('alter table ', TABLE_NAME, ' modify ', COLUMN_NAME, ' binary(16) ', IF (IS_NULLABLE = 'NO', 'not null', ''), ';') from information_schema.columns where TABLE_SCHEMA = 'my_table_name' and COLUMN_KEY in ('PRI', 'MUL') and COLUMN_NAME like 'id%'
select concat ('alter table ', TABLE_NAME, ' add constraint ', CONSTRAINT_NAME, ' foreign key (', COLUMN_NAME, ') references ', REFERENCED_TABLE_NAME, ' (', REFERENCED_COLUMN_NAME, ') on update cascade;') from information_schema.KEY_COLUMN_USAGE where table_schema = 'my_table_name' and CONSTRAINT_NAME like 'fk%'
select concat('update ', TABLE_NAME, ' set ', COLUMN_NAME, ' = unhex(replace(uuid(), ''-'', ''''));') from information_schema.COLUMNS where TABLE_SCHEMA = 'my_table_name' and md5(COLUMN_NAME) = md5('id')
select concat ('alter table ', TABLE_NAME, ' drop foreign key ', CONSTRAINT_NAME, ';') from information_schema.KEY_COLUMN_USAGE where table_schema = 'my_table_name' and CONSTRAINT_NAME like 'fk%'
select concat ('alter table ', TABLE_NAME, ' add constraint ', CONSTRAINT_NAME, ' foreign key (', COLUMN_NAME, ') references ', REFERENCED_TABLE_NAME, ' (', REFERENCED_COLUMN_NAME, ');') from information_schema.KEY_COLUMN_USAGE where table_schema = 'my_table_name' and CONSTRAINT_NAME like 'fk%'

Problem solved.

Community
  • 1
  • 1
Renan Ceratto
  • 130
  • 2
  • 12
  • Couldn't you just avoid all this by using last_insert_id() after "synchronization"? – Uueerdo Nov 10 '15 at 00:40
  • I'm doing it now... But when the Object is created on the client-side, after export I need to delete and re-import all the objects to get the "right" server ID... It's getting too complicated... Thats why I want to use UUID... so I don't need to fix the "wrong" client ID – Renan Ceratto Nov 10 '15 at 00:45
  • Ah, I assumed the process that did that would have access to update those id values without recreating; but I suppose if you are doing some sort of bulk/multi insert that is not feasible. Are there foreign keys, or any unenforced references to the existing id values? – Uueerdo Nov 10 '15 at 00:47
  • Yes.. I'm doing bulk insert with a hierarchical structure... e.g: Project object with department list. Each department was group list. Each group with items list – Renan Ceratto Nov 10 '15 at 00:56
  • 1
    I don't have time to compose a detailed answer, but I'd suggest: (1) add the new ids as new columns to all involved tables, (2) generate proper uuid() values in the tables whose id values are being replaced, (3) update related records' new reference values by JOIN on old id references, (4) drop old id fields, (5, optionally) rename new id fields to old names. – Uueerdo Nov 10 '15 at 01:06
  • I'll write some scripts and then I'll let you know. But I think I'll have troubles with Foreign Keys... I guess I will need to drop them all, update and recreate the FK's. Thanks. – Renan Ceratto Nov 10 '15 at 01:21
  • As far as I know, if you are changing the type of the field, you'd have had to do that anyway. – Uueerdo Nov 10 '15 at 18:25

0 Answers0