Προς το περιεχόμενο

Προβλημα σε mysql σχετικα με ξενο κλειδί


christian-ago

Προτεινόμενες αναρτήσεις

Δημοσ.

Εδω και πολυ ωρα προσπαθω με διαφορετικους τροπους να προσθεσω ξενο κλειδι σε ήδη δημιουργημένο πινακα στη mysql . Το μηνυμα λαθους που μου εμφανιζει ειναι:

>Key column 'cat_ID' doesn't exist in table

Τελικά μετά απο καμποσο ψαξιμο βρηκα μαλλον τις σωστες εντολες. Γραφω λοιπον:

>
alter table products
add constraint fk_products1
foreign key(cat_ID)
references categories(cat_ID)

 

Ο products ειναι ο πινακας που θελω να βαλω το ξενο κλειδι.

Το cat_ID ειναι το ξενο κλειδι πο θελω να βαλω και ειναι primary key στον πινακα categories.

Και οι δυο πινακες εχουν τη μηχανη innodb.

Αν αμελησα κατι πειτε μου. Ευχαριστω παιδια.

Δημοσ.

ετσι οπως ειναι γραμμενη η εντολή "alter...κλπ" , νομιζω πρεπει ηδη να υπαρχει πεδίο cat_ID στον products.

υπάρχει?

 

 

ισως πρεπει να προηγηθει μια αλλη, κατι σαν:

alter table products add column cat_ID μπλα, μπλα... (ιδιο type & size με το categories.cat_ID που επίσης προ-υπάρχει)

Δημοσ.

Τσεκαρω μεσα απο το γραφικο περιβαλλον του Mysql Query Browser

και δεν υπαρχει στηλη με ονομα cat_ID.

Υπαρχει ομως στον πινακα categories το cat_ID και ειναι πρωτευων κλειδι.

 

Εννοεις οτι πρεπει να προσθεσω πρωτα στηλη στον πινακα products και μετα να ορισω ξενο κλειδι; Αυτη δηλαδη ειναι η στανταρ διαδικασια; Δεν το ξερω, ειμαι αρκετα νεος στη Mysql.

 

---------- Προσθήκη στις 14:25 ---------- Προηγούμενο μήνυμα στις 14:18 ----------

 

Τελικα ναι, πρωτα προσθετω στηλη και μετα το κανω κλειδι.

Επομενως, αφου εχω τη στηλη cat_ID στον πινακα products θελω να την κανω ξενο κλειδι.

Γραφω λοιπον:

>alter table products
add constraint cat_ID
foreign key(cat_ID)
references categories(cat_ID)

 

και παιρνω ως ανταλλαγμα το εξης:

>Cannot add or update a child row: a foreign key constraint fails (`emarket`.`#sql-30c_b`, CONSTRAINT `cat_ID` FOREIGN KEY (`cat_ID`) REFERENCES `categories` (`cat_ID`))

 

Προφανως κανω κατι λαθος. Δεν καταλαβαινω ποια ειναι η στανταρ διαδικασια για να κανω καποια στηλη ξενο κλειδι.

Γιατι μεσα απο το γραφικο περιβαλλον δεν μπορω.

Δημοσ.

αυτο που εκανες τωρα

>alter table products
add constraint [b]cat_ID[/b]  <----------(*)
foreign key(cat_ID)
references categories(cat_ID)

 

 

δεν ειναι ιδιο με αυτο που προσπαθουσες πριν

>
alter table products
add constraint [b]fk_products1[/b] <----------(*)
foreign key(cat_ID)
references categories(cat_ID)

 

αυτο με τον αστερισκο ειναι το όνομα του constraint. οχι του πεδίου.

 

constraint ειναι εναν "Περιοριστικός Κανόνας".

ενας κανονας που μπορει να λεει πχ. "Στη στηλη Κατ_ΙΔ του πινακα Προιοντα, απαγορευεται να αποθηκευονται τιμές που δεν εχουν προηγουμένως αποθηκευτεί στη στηλη Κατ_ΙΔ του πινακα Κατηγορίες".

στον κανόνα δινουμε ενα όνομα, πχ. "fk_products1" απλα για λογους αναφοράς.

καλυτερα μην βαζεις το ιδιο ονομα με το ονομα του πεδίου (Αν στο επιτρέπει η mysql. Δεν ξερω αν αυτο ειναι η αιτία).

 

--------------------------------------------------------

 

Ερώτηση: Οι σχετικοι πινακες (προιοντα και κατηγορίες ) έχουν εγγραφές ή ειναι άδειοι;

Εχεις τη δυνατοτητα να τους αδειάσεις, ή όχι (προκειται για παραγωγικό συστημα) ;

 

Αν περιέχουν εγγραφες την ωρα που κανεις τα Αλτερ, τοτε πρεπει οι εγγραφές αυτες να υπακούουν στον νέο κανόνα που δημιουργείς.

Δημοσ.

Πρωτον ευχαριστω για τις αμεσες αποκρισεις σου, ψαχνω εδω και ωρες και δεν βρισκω τη λυση.

Λοιπον αλλαξα τον κωδικα και τον εκανα οπως πριν (με ονομα κανονα διαφορερικο απο το κλειδι) αλλα τωρα παιρνω το μηνυμα:

>Can't create table 'emarket.#sql-30c_10' (errno: 121)

Το emarket ειναι η βαση μου.

Οι πινακες εχουν εγγραφες, δηλαδη εχω συμπληρωσει πχ τον πινακα products με διαφορα προιοντα. Τη δευτερη ερωτηση δεν την καταλαβα (λιγακι ορολογια...)

Για το τελευταιο που λες κατι μου μυριζει, αλλα θες να το εξηγησεις λιγο;

Δηλαδη οταν οριζω ξενο κλειδι, οι εγγραφες πρεπει να ειναι κενες;

Δημοσ.

Tο "Can't create table 'emarket.#sql-30c_10' (errno: 121)" δεν ξερω τι ειναι και δεν μπορω τωρα να ψαξω. Δεν εχω εμπειρια συγκεκριμενα στη mysql. Διαβασε το documentation.

 

--------------------------

 

 

"Οι πινακες εχουν εγγραφες, δηλαδη εχω συμπληρωσει πχ τον πινακα products με διαφορα προιοντα"

OK, λοιπον, ο πινακας των κατηγοριών έχει εγγραφές?

Οι κατηγορίες των προιοντων (τα cat-id τους) υπαρχουν όλα καταχωρημενα στον πινακα κατηγορίες;

 

Εχω την εντύπωση οτι θες να φτιάξεις ξενο κλειδι, χωρις να καταλαβαινεις σε τι χρησιμευει. Γιατι θες να το φτιάξεις;

(επειδη το γραφει η εκφωνηση μιας ασκησης; )

αυτο που λεμε "¨ξενο κλειδι" / FK, ειναι ενα είδος constraint.

υπαρχουν και άλλα ειδη constraint.

τι ειναι constraint? το εξηγησα πανω. ενας κανόνας.

 

προσπαθησε να κανεις ολα αυτα σε αδειους πινακες, σε αλλη βαση,

και αν πετυχουν, βρηκες την αιτια (φταιει που ηταν γεματοι).

αν παθαινεις τα ιδια, βλέπουμε.

Δημοσ.

Λοιπόν για το foreign key πρέπει

 

1. Ίδιο πεδίο ακριβώς και στους δύο πίνακες ( Δηλ. Τύπος , Μέγεθος ). Το όνομα δεν χρειάζεται να είναι ίδιο

2. Και οι δύο πίνακες σίγουρα με engine innodb

3. Να μην υπάρχει ήδη το ίδιο όνομα constraint

4.To foreign key να κάνει reference primary key ή γενικότερα indexed πεδίο. Το ίδιο θα δημιουργήσει απο μόνο του τον αντίστοιχο index.

Δημοσ.

Οσον αφορα το 1. πιστευω οτι ο κωδικας μου το κανει αυτο.

Για το 2. παρολο που μου λεει στα settings του προγραμματος οτι η innodb ειναι η

default engine, οταν φτιαχω οποιονδηποτε πινακα μεσω εντολων βλεπω οτι δεν

δημιουργειται με την innodb.

Το 3. δεν το καταλαβαινω τι σημαινει, μπορεις να μου το εξηγησεις;

Τελος το 4. που λες, συμφωνα με τον κωδικα μου το πραγματοποιω;

Δηλαδη βλεπω μεσα απο το γραφικο περιβαλλον οτι το πρωτευων κλειδι

που θελω να κανω ξενο, εχει ευρετηριο, αρα το κανω σωστα;

Δημοσ.

To 3 σημαίνει ότι δεν πρέπει να δώσεις όνομα που να υπάρχει ήδη.

Δηλαδή αυτό που δείχνω παρακάτω με bold αν υπάρχει ήδη θα σκάσει

alter table products

add constraint fk_products1

foreign key(cat_ID)

references categories(cat_ID)

 

Δώσε ένα όνομα περίεργο και ξαναδοκίμασε . Δώσε πχ fk_categ_to_product_key

 

Aν δεν παίξει δώσε το full error

 

Για το 4 αν κάνεις reference primary key δεν έχεις πρόβλημα. Ηδη εχει δημιουργηθεί ο index.

 

---------- Προσθήκη στις 22:26 ---------- Προηγούμενο μήνυμα στις 21:55 ----------

 

Αν δεν βρίσκεις άκρη ακόμα και σου βγάλει error πάνω κάτω οπως πριν δηλαδή

Can't create table 'emarket.#sql-30c_10' (errno: 121)

 

Γράψε στην κονσόλα

show innodb status

και δείξε τι σου έβγαλε

Δημοσ.

Σου εστειλα ενα screenshot απο το προγραμμα να δεις το μηνυμα λαθους.

Εχω αρχισει να πιστευω οτι το προβλημα προερχεται απο αλλου δηλαδη απο πρωταρχικο σταδιο. Γιατι μια διαδικασια εισαγωγης ξενου κλειδιου ειναι κατι απλο,

δεν κανω δηλαδη κατι εξειδικευμενο οποτε θα αντιμετωπιζω αναλογη δυσκολια.

 

---------- Προσθήκη στις 23:08 ---------- Προηγούμενο μήνυμα στις 23:05 ----------

 

Μου εβγαλε ενα ενδιαφερον:

 

>
=====================================
100623 23:06:54 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 0 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 4, signal count 4
Mutex spin waits 0, rounds 13, OS waits 0
RW-shared spins 6, OS waits 3; RW-excl spins 1, OS waits 1
------------------------
LATEST FOREIGN KEY ERROR
------------------------
100623 22:55:16 Transaction:
TRANSACTION 0 2817, ACTIVE 0 sec, OS thread id 2852 inserting, thread declared inside InnoDB 499
mysql tables in use 2, locked 2
5 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 3, query id 124 localhost 127.0.0.1 Christian copy to tmp table
alter table products
add constraint fk_prdsaddasda
foreign key(cat_ID)
references categories(cat_ID)
Foreign key constraint fails for table `emarket`.`#sql-7f0_3`:
,
 CONSTRAINT `fk_prdsaddasda` FOREIGN KEY (`cat_ID`) REFERENCES `categories` (`cat_ID`)
Trying to add in child table, in index `fk_prdsaddasda` tuple:
DATA TUPLE: 2 fields;
0: len 0; hex ; asc ;; 1: len 5; hex 615f303031; asc a_001;;

But in parent table `emarket`.`categories`, in index `PRIMARY`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 1; hex 30; asc 0;; 1: len 6; hex 00000000070a; asc       ;; 2: len 7; hex 800000002d0110; asc     -  ;; 3: len 5; hex 426f6f6b73; asc Books;;

------------
TRANSACTIONS
------------
Trx id counter 0 2821
Purge done for trx's n:o < 0 2820 undo n:o < 0 0
History list length 6
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, OS thread id 1740
MySQL thread id 7, query id 165 localhost 127.0.0.1 Christian
show innodb status
--------
FILE I/O
--------
I/O thread 0 state: wait Windows aio (insert buffer thread)
I/O thread 1 state: wait Windows aio (log thread)
I/O thread 2 state: wait Windows aio (read thread)
I/O thread 3 state: wait Windows aio (write thread)
Pending normal aio reads: 0, aio writes: 0,
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
50 OS file reads, 38 OS file writes, 12 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2,
0 inserts, 0 merged recs, 0 merges
Hash table size 69257, node heap has 1 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 0 192073
Log flushed up to   0 192073
Last checkpoint at  0 192073
0 pending log writes, 0 pending chkp writes
13 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 31653582; in additional pool allocated 1394048
Dictionary memory allocated 24888
Buffer pool size   1024
Free buffers       981
Database pages     42
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 40, created 2, written 28
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread id 3544, state: waiting for server activity
Number of rows inserted 0, updated 0, deleted 0, read 1
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

 

 

Τι σημαινει;

Δημοσ.

H στήλη cat_id στο πίνακα Products έχει δεδομένα που δεν αντικατοπτρίζονται στο reference πεδίο cat_id του πίνακα categories. Κοινώς κάποια τιμή στην στήλη

product.cat_id δεν υπάρχει στον πίνακα categories.

 

Λύση. Κοίτα τι δεδομένα έχεις μέσα στην στήλη product.cat_id και κοίτα να υπάρχουν στο πεδίο categories.cat_id. Μόλις τα φτιάξεις τότε φτιάξε τον foreign key constraint.

 

Παράδειγμα

 

>[b]Λάθος[/b]
--------------------------------------------------------
TABLE PRODUCT                 TABLE_CATEGORIES
ID        CAT_ID                    CAT_ID
1          1                             2    ??????? Δεν υπάρχει εδώ το 1
2          2                             3

Το 1 στο πεδίο product.cat_id δεν υπάρχει στον πίνακα CATEGORIES

[b]Σωστό[/b]
--------------------------------------------------------
TABLE PRODUCT                 TABLE_CATEGORIES
ID        CAT_ID                    CAT_ID
1          1                             1
2          2                             2
                                          3

Δημοσ.

Εισαι κορυφη φιλε, με εφτιαξες τωρα. Παιδευομουν τοση ωρα για αυτη τη παπαρδελα.

Τελικα συμπερασμα ειναι οτι δεν πρεπει να γεμιζω με δεδομενα πριν παιξω με κλειδια.

Βιαστηκα να δοκιμασω την βαση μου στην php γι αυτο. Ευχαριστω αγορι ;)

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...