Domanda

Ho una tabella con un singolo campo unico VARCHAR (512). Voglio avere un altro tavolo in possesso di un riferimento di chiave esterna a questo primo tavolo. Entrambe le tabelle utilizzano InnoDB. Se posso aggiungere una chiave VARCHAR (512) alla seconda tabella e aggiungere un vincolo di chiave esterna sarà dati lungo 512 byte si terrà due volte?

Se è così, c'è un modo per contenere solo un riferimento all'indice e non al varchar stesso?

In breve, la mia domanda è, in InnoDB c'è un modo efficace per tenere le chiavi esterne ai campi VARCHAR lunghi?

La ringrazio molto,

Yaniv

È stato utile?

Soluzione

Sì, se si dispone di una colonna VARCHAR(512) sulla tabella di riferimento, esisteranno due volte i dati.

Vi consiglio di fare riferimento a una chiave primaria intero per la prima tabella, non i dati di 512 byte di chiave esterna della tabella di riferimento. Questa è una specie di ciò che la normalizzazione è tutto.

Altri suggerimenti

Ho eseguito un semplice test: creare 3 tavoli, uno per contenere i dati stessi con due colonne, e l'ID (int) ei dati (varchar [120]), un altro tavolo che utilizza l'ID come chiave esterna e un ultimo uno che utilizza i dati come chiave esterna:

CREATE TABLE `dados` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`) USING BTREE,
  KEY `idx` (`id`,`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `refINT` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `dado` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`dado`),
  CONSTRAINT `id` FOREIGN KEY (`dado`) REFERENCES `dados` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `refSTR` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `dado` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `nome` (`dado`),
  CONSTRAINT `nome` FOREIGN KEY (`dado`) REFERENCES `dados` (`name`) ON DELETE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Inserito 100 record in ogni tabella e rispetto la dimensione finale tabella:

dados:  192.0 KB
refINT: 32.0 KB
refSTR: 32.0 KB

Quindi credo che i dati non vengono replicati in chiave esterna varchar, beh, almeno in MySQL 5.1 versione.

Mantenere la dimensione della chiave piccola è sempre buona. Si potrebbe aggirare il problema di avere una grande VARCHAR indicizzato da invece avere una colonna checksum aggiuntiva che si genera in fase di inserimento. Questo campo checksum conterrebbe l'output di un algoritmo di hashing CRC32() o forse MD5() della colonna più grande.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top