MySQL: Tabellen zusammenfügen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

MySQL: Tabellen zusammenfügen

Beitrag von eliot » 07.02.2006 16:43:22

Hallo,

ich stehe hier vor einem mehr oder weniger großen Problem.
Ich habe Unternehmen welche Kunden über eine Kundennummer
indentifizieren. Beide Unternhemen nehmen im Laufe eines Arbeitstages
neue Kunden auf. Nach dem Arbeitstag sollen die Kunden Tabellen abgeglichen,
sodass der Kunde in beiden Unternehmen mit gleichen Kundennummer bekannt ist.
Da wir aber nicht vom Internet abhängig sein wollen, steht in jeder Firma
jeweils ein MySQL-Server. Die Tabellen sollen nach Arbietsende abgeglichen werden.

Stellt sich natürlich die Frage nach dem primary Key? Ich darf in keiner der
beiden Tabellen die Keys ändern, wie stelle ich aber sicher, dass sie sich
unterscheiden???

stehe irgendwie gerade völlig auf dem Schlauch :(

regards

eliot

ding280
Beiträge: 324
Registriert: 15.04.2005 18:31:18

Beitrag von ding280 » 07.02.2006 17:30:23

Hallo,

wird denn ein Datum mit eingefügt? Dann nimm doch einfach alle, die an einem Tag eingefügt wurden. Mach das in beiden Tabellen und füge anschließend die Daten des jeweils anderen ein.

Gruß Tom

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 07.02.2006 18:21:47

Das Probllem, das ich sehe ist, daß MySQL den Zähler des "AUTO INCREMENT" nicht zurücksetzt, wenn man den letzten Eintrag entfernt (so habe ich es zumindest in Erinnerung). Zuerst müßtest du in die Datenbank, dessen letzte Kundenid niedriger ist, soviele "DummyKunden" einfügen bis beide Zähler gleich sind, und danch alle Kunden vom Tag aus beiden Datenbanken entfernen und gleichzeitig in beide Datenbanken einfügen.

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Beitrag von eliot » 07.02.2006 22:55:23

ding280 hat geschrieben:Hallo,

wird denn ein Datum mit eingefügt? Dann nimm doch einfach alle, die an einem Tag eingefügt wurden. Mach das in beiden Tabellen und füge anschließend die Daten des jeweils anderen ein.

Gruß Tom
Das hätte aber den Effekt, dass die IDs in den beiden Tabellen des eiegtlich gleichen
Kuden unterschiedlich sind, und damit auchdie Kundenummer.
Da die Kunden aber gleich der ID ist, und diese auch auf der Kudenkarte gedruckt ist,
wäre der Kunde nur einem der beiden Unternehmen bekannt.

Knifflliges Ding, ein Server wäre die Lösung, dies würde aber für eines der beiden
Unternehmen bedeuten, dass es Internetzugang abhängig ist. Das wäre sehr schlecht.

Ein "sprechender" Key wäre auch eine Lösung, wenn auch eine sehr schelchte.

Gibt es nicht die Möglichkeit, einen Primary Key über 2 Spalten zu machen???
In der Form: 1 Spalte: auto_increment + 2. Spalte Firmen Kennung
Das würde das Problem lösen, ist aber unter MySQL nicht möglich :(
soweit ich weiß, ...

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 08.02.2006 01:26:42

Wie wäre es eine weitere Spalte an zu legen, in die dann die KundenID der anderen Firma eingetragen wird (Allso nicht "auto increment" oder sowas). Dadurch müßte man doch immer alle Kunden eindeutig Zuordnen können. Man muß nur Unterscheiden können welche DB welcher Firma gehört. :-) (Wenn möglich könnte man auch sowas wie "ID-Firma1" und "ID-Firma2" machen.) Und ich sehe da auch kein Problem mit dem "PrimaryKey" denn so weit ich das noch weiß kann man bei MySQL mehrer Primäre Suchschlüssel anlegen.

Korrektur:

Es kann tatsächlich nur einen primären Schlüssel geben, aber du kannst jeden Datentyp auch "UNIQUE" machen. damit darf er nur einen eindeutigen Wert annehmen. Wenn du dann noch einen "KEY" auf die Spalte setzt, kannst du auch schnell danach suchen.

Ungefähr so...
Bei Firma1:

Code: Alles auswählen

ID-FIRMA1 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA2 INT UNIQUE KEY
Bei Firma2:

Code: Alles auswählen

ID-FIRMA2 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA1 INT UNIQUE KEY
Das muß jetzt nicht 100% richtig sein, aber so ähnlich sollte es funktionieren.

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Beitrag von eliot » 08.02.2006 09:15:03

ToPeG hat geschrieben:Wie wäre es eine weitere Spalte an zu legen, in die dann die KundenID der anderen Firma eingetragen wird (Allso nicht "auto increment" oder sowas). Dadurch müßte man doch immer alle Kunden eindeutig Zuordnen können. Man muß nur Unterscheiden können welche DB welcher Firma gehört. :-) (Wenn möglich könnte man auch sowas wie "ID-Firma1" und "ID-Firma2" machen.) Und ich sehe da auch kein Problem mit dem "PrimaryKey" denn so weit ich das noch weiß kann man bei MySQL mehrer Primäre Suchschlüssel anlegen.

Korrektur:

Es kann tatsächlich nur einen primären Schlüssel geben, aber du kannst jeden Datentyp auch "UNIQUE" machen. damit darf er nur einen eindeutigen Wert annehmen. Wenn du dann noch einen "KEY" auf die Spalte setzt, kannst du auch schnell danach suchen.

Ungefähr so...
Bei Firma1:

Code: Alles auswählen

ID-FIRMA1 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA2 INT UNIQUE KEY
Bei Firma2:

Code: Alles auswählen

ID-FIRMA2 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA1 INT UNIQUE KEY
Das muß jetzt nicht 100% richtig sein, aber so ähnlich sollte es funktionieren.
Moin, hey, das hört sich garnicht so schelcht an!
Werde das heute Nachmittag mal durchspielen, aber auf den ersten Blick
echt pfiffig! Nur würde mich diese Lösung auf 2 Firmen beschränken,
was aber durch aus in Ordnung geht, eine allgemein Lösung für dieses
Problem wird es wohl auch nicht geben (also im Sinne von x Firmen)

Benutzeravatar
C_A
Beiträge: 1082
Registriert: 22.04.2004 14:51:01
Lizenz eigener Beiträge: GNU General Public License

Beitrag von C_A » 08.02.2006 09:35:16

eliot hat geschrieben: Gibt es nicht die Möglichkeit, einen Primary Key über 2 Spalten zu machen???
In der Form: 1 Spalte: auto_increment + 2. Spalte Firmen Kennung
Das würde das Problem lösen, ist aber unter MySQL nicht möglich :(
soweit ich weiß, ...
Ich hab mich mit dem eigentlichen Problem jetzt nicht wirklich beschaeftigt, wollte aber nur sage dass es durchaus moeglich ist eine Tabelle mit einem Primary Key ueber zwei Spalten zu erstellen:

Code: Alles auswählen

mysql> create table primt ( bla1 int unsigned auto_increment , bla2 int, primary key (bla1, bla2));
Query OK, 0 rows affected (0.00 sec)

mysql> describe primt;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| bla1  | int(10) unsigned |      | PRI | NULL    | auto_increment |
| bla2  | int(11)          |      | PRI | 0       |                |
+-------+------------------+------+-----+---------+----------------+
wurde auf mysql v4.1.12 ausgefuert
sorry fuer den haesslichen output ;)

DeletedUserReAsG

Beitrag von DeletedUserReAsG » 08.02.2006 09:47:20

Hab nun nicht viel Ahnung vom Datenbankdesign, aber ich würde die jeweilgen Primaries nur zum Sortieren benutzen, und die Kundennummer mit einem Präfix für die jeweilige Firma versehen:
Kunde 0815 über Firma A aufgenommen erhält Kundennummer A-0815 und wenn Firma B zufällig an diesem Tag die gleiche Nummer an einen Kunden vergibt, bekommt der halt Kundennummer B-0815. Dann kann man am Ende des Tages alles in eine DB schmeißen, die Primaries ggf. neu anlegen und hat keine Probleme mit Kollisionen oder ähnlichen Sachen.

(Ich hoffe, ich habe das Problem überhaupt erkannt...)

cu

Benutzeravatar
C_A
Beiträge: 1082
Registriert: 22.04.2004 14:51:01
Lizenz eigener Beiträge: GNU General Public License

Beitrag von C_A » 08.02.2006 09:51:03

ToPeG hat geschrieben:Bei Firma1:

Code: Alles auswählen

ID-FIRMA1 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA2 INT UNIQUE KEY
Bei Firma2:

Code: Alles auswählen

ID-FIRMA2 INT AUTO_INCREMENT PRIMARY KEY,
ID-FIRMA1 INT UNIQUE KEY
Das muß jetzt nicht 100% richtig sein, aber so ähnlich sollte es funktionieren.
Moechte noch was kurz zu meiner "Ausfuehrung" sagen, verglichen mit dem oberen Beispiel mit UNIQUE ist es in meiner Tabelle (primt) durchaus moeglich 2 Werte in Spalte bla2 zu haben die identisch sind. Es ist aber nicht moeglich eine Kombination vun bla1 und bla2 zwei man zu haben - was aber eigentlich schon durch das auto_increment vermieden wird.

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Beitrag von eliot » 08.02.2006 14:06:01

Vielen Dank für die rege Teilnahme an dieser Diskussion,
das finde ich echt super an der Linux Gemeinde, sowas hat man
bei andere Systemen leider nicht! Ich habe mittlerweile des Rätsels Lösung!

Ich möchte in der Betribesanzahl nicht beschränkt sein, die bisherigen Lösungen
würde aber immer nur für 2 Betriebe/Tabellen funktionieren. Hier also mein Lösungs-
ansatz:

Kennung_Firma 1: 11
Kennung_Firma 2: 12

Dem Client ist bekannt in welcher Firma er steht.
Pro Firma ein Server mit Tabelle Kunde und folgenden Spalten:
ID (int, auto_increment, primary key) | Kundennummer (int, unique)

Wird ein neuer Kunde angelegt, so wird er in in der Datenbank gespeichert,
die Kundenummer wird noch nicht generiert. Erst wenn ich die Kundenkarte Drucke,
generiert mir der Client eine Kundenummer nach folgender Formel:

Kundennummer = ID + (Kennung_Firma * 1000000)

jetzt wird dieses in die Datenbank gespeichert.
Damit kann ich x Firmen haben, alle mit ihrer eigenen Kennung.
Jede Firme kann 999999 Kunden haben, bevor sich die Knundenummer
mit einer Kennung der nächsten Firma überschneidet.
Ein späteres Einfügen der der Daten in die jeweils andere Tabelle
einer Firma stellt dmit kein Problem mehr, da die Kundennummer unabhängig
der ID in der Tabelle ist.

Was haltet ihr davon???

regards

eliot

tapferesschneiderlein
Beiträge: 189
Registriert: 11.08.2005 09:27:01

Beitrag von tapferesschneiderlein » 08.02.2006 14:46:13

Ich habe noch nicht ganz verstanden, was eigentlich gegen die Zweispalten-Variante spricht, bei der man nicht vorher überlegen muß, wieviele Kunden jede Firma hinzufügen darf usw.:

Code: Alles auswählen

CREATE TABLE `kunden` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `firma` INT(11) UNSIGNED NOT NULL DEFAULT '0',
  `kunde` VARCHAR(255),
  PRIMARY KEY  (`id`, `firma`)
);
Wenn man will, kann man sogar pro Standort den Default-Wert der Spalte »firma« anpassen, so daß sich die Clientsoftware darum überhaupt keine Gedanken machen muß ...

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 08.02.2006 15:52:07

An sich ist deine Lösung die eleganteste.
Wenn ich es richtig verstanden habe, soll es aber ein explizides Feld "Kundennummer" geben, über das jeder Kunde Firmenunabhängig identifiziert werden kann.
Wenn die Kundennummer nicht explizit eine Zahl sein muß kann man ja auch ein Textfeld verwenden und Firmennummer einfach vor die ID des Feldes setzen. Damit hätte man eine eindeutige Indentifizierung. ( Wäre vergleichbar mit: $FirmenID*(10**length($KundenID))+$KundenID )

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Beitrag von eliot » 08.02.2006 16:03:41

tapferesschneiderlein hat geschrieben:Ich habe noch nicht ganz verstanden, was eigentlich gegen die Zweispalten-Variante spricht, bei der man nicht vorher überlegen muß, wieviele Kunden jede Firma hinzufügen darf usw.:

Code: Alles auswählen

CREATE TABLE `kunden` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `firma` INT(11) UNSIGNED NOT NULL DEFAULT '0',
  `kunde` VARCHAR(255),
  PRIMARY KEY  (`id`, `firma`)
);
Wenn man will, kann man sogar pro Standort den Default-Wert der Spalte »firma« anpassen, so daß sich die Clientsoftware darum überhaupt keine Gedanken machen muß ...
Ups, diese Lösung ist natürlich noch besser! Ich dachte es wäre in MySQL nicht möglich,
Promary Keys über 2 Spalten zu machen, anscheinend geht das doch.
Werde dies wohl als erstes probieren, danke!

EDIT: Hier ist wieder folgendes Problem:
Wie gleiche ich die beiden Kunden Tabellen der einzelnen Firmen
ab??? Jeden Kuden einzelen hinzufügen geht nicht, da sich hier
dann wieder ID ändern würde, und damit die Kundennummer nicht mehr
übereinstimmt.

EDIT2:

Sorry, aber ich glaube ich hätte eine Möglichkeit wie dieses
zu bewrkstelligen ist. Einfach von beiden Servern die Tabelle Kunde
extrahieren, Ein SELECT * FROM tabelle1 UNION SELECT * FROM tabelle2
Diese Tabelle als aktuelle speichern, et voilà!

Am I right???
Zuletzt geändert von eliot am 08.02.2006 16:24:40, insgesamt 1-mal geändert.

tapferesschneiderlein
Beiträge: 189
Registriert: 11.08.2005 09:27:01

Beitrag von tapferesschneiderlein » 08.02.2006 16:24:17

Die eindeutige Kundennummer würde sich dann aus beiden Spalten zusammensetzen. Beispielsweise »815-4711«.
Diese kann auch immer durch

Code: Alles auswählen

SELECT CONCAT( firma, "-", id ) ...
dargestellt werden.
Bei der Suche geht das dann auch, wobei ich aber denke, daß da dann ein

Code: Alles auswählen

WHERE firma = 815 AND id = 4711
performanter ist ...

tapferesschneiderlein
Beiträge: 189
Registriert: 11.08.2005 09:27:01

Beitrag von tapferesschneiderlein » 08.02.2006 16:34:33

Ein SELECT * FROM tabelle1 UNION SELECT * FROM tabelle2
Oder

Code: Alles auswählen

INSERT IGNORE INTO `table_in_firma_1` SELECT * FROM `table_in_firma_2`
und umgekehrt ...

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Beitrag von eliot » 08.02.2006 17:10:58

tapferesschneiderlein hat geschrieben:
Ein SELECT * FROM tabelle1 UNION SELECT * FROM tabelle2
Oder

Code: Alles auswählen

INSERT IGNORE INTO `table_in_firma_1` SELECT * FROM `table_in_firma_2`
und umgekehrt ...
oder so :)

Dabei werden schon vorhandene PRIMARY KEYS ignoriert, und der auto increment nicht
benutzt, da ja schon id's vorhanden sind???

Prima, dann ist das wohl der kürzeste Weg, ...

Danke!

Antworten