Door
Jan R
op 29-08-2021 19:16
gewijzigd op 29-08-2021 19:17
4.593 views
Hi
Ik werkte in het verleden met tabellen via een prefix. Nu zou ik deze tabellen willen samenvoegen met een id van herkomst of iets dergelijks.
Hoe pak ik dit het beste aan?
Sowieso de kleinste tabellen toevoegen aan de grootste lijkt me het beste. maar de gelinkte id's moeten wel volgen natuurlijk.
Ik kan natuurlijk zelf een conversie doorvoeren via "record per record" en de links verbeteren maar werken via insert from lijkt me toch sneller en efficienter.
#bron w3schools
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
Jan
?Onbekende gebruiker
30-08-2021 08:15
Beetje vage beschrijving, misschien kan je er een voorbeeld bij geven?
Algemeen gesproken is alles in SQL een tabel. Als je twee tabellen samenvoegt tot 1 resultaat met bijvoorbeeld een LEFT JOIN, dan is de uitkomst een resultaattabel. Die kan je weer opslaan in een nieuwe tabel met een INSERT INTO tabel (col1, col2, ...) SELECT ...
Als je ID's recursief zijn maak je gebruik van een recursieve common table expression.
Je ziet dat de tabellen beginnen met trn_ een andere groep begint met tr2_
De id's van alle tabellen beginnen logisch met 1.
Dus in trn_groep, totaal 3 records, heb je id 1 maar ook in tr2_groep. Dus als ik deze samenvoeg wordt het id in trn_groep 4 welkde slechts 1 records heeft.
gevolg alles met verwijzing groepid uit tr2_ moet aangepast worden van 1 naar 4 tijdens de importatie
Dit loopt verder uit met de toernooien ±50 en 3 records welke weer moeten overgenomen worden in de partijen, 3570+96 records, en de spelers, 469+26 records.
Als de tabellen die je wilt samenvoegen dezelfde structuur hebben, kun je het waarschijnlijk het gemakkelijkst en veiligst oplossen met een numerieke prefix.
Stel, de grootste tabel bevat minder dan 20.000 records. Je kunt dan 2000 toevoegen voor de ID's in de kleinere tabel:
- 1 wordt 20001
- 2 wordt 20002
- 3 wordt 20003
enzovoort
Ik zou dat zelf even doen met zoeken en vervangen in een export van de SQL-data, zodat je ziet wat je doet, maar je kunt de operatie ook uitvoeren met de stringfunctie CONCAT() in SQL.
Beiden bedankt. ik hoopte op minder werk :) maar dacht al dat dit de beste oplossing zou zijn.
resumeren
1. FK relaties aanmaken
2. update table ... set id=id + max_van_andere_tabel voor elke tabel
3. tabellen samenvoegen
PS ik maak geen fk relaties omdat mijn restore-script hier problemen mee heeft. Eerst worden de tabellen verwijderd dan opnieuw aangemaakt en dan opnieuw gevuld.
[code]
DROP TABLE IF EXISTS dvd_films;
CREATE TABLE dvd_films (
id int(11) NOT NULL AUTO_INCREMENT,
titel varchar(50) NOT NULL,
subtitels text NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=242 DEFAULT CHARSET=utf8;
INSERT INTO dvd_films VALUES("1", "3 FAMILY MOVIES", "");
# en dan nog 241 records natuurlijk
[code]
Bij het verwijderen lukt het niet omdat de andere, benodigde, tabel nog bestaat.
in zo'n geval is het verstandiger om de check tijdelijk uit te zetten in plaats van helemaal niet te gebruiken:
SET FOREIGN_KEY_CHECKS=0;
SET FOREIGN_KEY_CHECKS=1;
zowel bij verwijderen als inserten van records in willekeurige volgorde.
Al lijkt me een restore iets wat je normaal op een hele database doet en niet per losse tabel.
Omdat one.com geen backups kent moet ik me behelpen met een script.
Script loopt door de db een maakt een restorescript aan
inhoud restorescript(sql bestand)
1 verwijder tabel
2 maak de tabel opnieuw met de indexen
3 voeg records toe
4 ga naar volgende tabel en keer terug naar punt 1 indien er nog tabellen zijn.
Ik ben dus vollop bezig met de CONSTRAINT's aan te maken. Ik heb er al 48. Ik heb er echter ook 1tje die niet verplicht een link heeft.
Het gaat zoals meestal weer over schaken:) maar soms heeft iemand geen tegenstander. In dat geval wordt naar gelang de reden -2,-1 of 0 gebruikt. Deze tegenstanders bestaan niet. Ze worden hardcoded opgevangen als vrijwillig niet spelen, geen tegenstander en afwezig.
Behalve ze in elk toernooi aanmaken is er eventueel een oplossing hiervoor?
ALTER TABLE ldr_partijen ADD CONSTRAINT Fk_143 FOREIGN KEY (wit) REFERENCES ldr_spelers (id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE ldr_partijen ADD CONSTRAINT Fk_144 FOREIGN KEY (zwart) REFERENCES ldr_spelers (id) ON DELETE CASCADE ON UPDATE CASCADE;
De 1° lukt dus maar de 2° niet omdat zwart -2 tot 0 kan zijn welke niet bestaan in de database.
Jan
?Onbekende gebruiker
03-09-2021 20:23
Als er geen record bestaat waar naar verwezen kan worden, is het gebruikelijk om in de kolom met de FK-contraint een NULL te zetten. Dat is geen probleem voor de FK-constraint, die controleert alleen maar of de waarde waar naar verwezen wordt bestaat, als er überhaupt een waarde is opgegeven.
Aannemende dat 0 de niet-bestaande waarde is, kan je kiezen om 0 toe te voegen in de andere tabel, of 0 te vervangen voor NULL.
Dat is een uitgedachte output om een database mee te restoren. (of alleen de data, of alleen de tabellen/view, evt in- of exclusief procedures etc).
Dat werkt altijd beter dan een eigen script, waarbij je zoals hier tegen FK restricties aanloopt. Die FK-check regel zul je dan ook vaak in de output van mysqldump zien staan.