कैसे दो टेबल MySQL की विरासत के मॉडल के लिए


14

मेरे पास कुछ टेबल हैं जहां मैं डेटा स्टोर करता हूं और उस व्यक्ति (कार्यकर्ता, नागरिक) के प्रकार पर निर्भर करता है जो मैंने एक eventटेबल में इसे स्टोर करना चाहता था , अब ये लोग एक जानवर को बचाते हैं (एक animalटेबल है)।

अंत में, मैं इस घटना को संग्रहीत करने के लिए एक तालिका रखना चाहता हूं कि एक आदमी (कार्यकर्ता, नागरिक), एक जानवर को बचाया, लेकिन धनुष मुझे एक विदेशी कुंजी जोड़ना चाहिए या idउस नागरिक या कार्यकर्ता के मूल्य को कैसे जानना चाहिए जिसने काम किया था?

अब, इस डिज़ाइन में मुझे नहीं पता कि किस व्यक्ति से कैसे संबंध स्थापित किया जाए, यदि मेरे पास केवल एक प्रकार का व्यक्ति (उर्फ सिविल) होता तो मैं केवल इस अंतिम तालिका civil_idमें एक personकॉलम में वेले को संग्रहीत करता ... लेकिन कैसे पता है कि यह नागरिक या कार्यकर्ता था, क्या मुझे अन्य "मध्यवर्ती" तालिका की आवश्यकता है?

MySQL में निम्न आरेख के डिज़ाइन को कैसे प्रतिबिंबित करें?

यहाँ छवि विवरण दर्ज करें

अतिरिक्त जानकारिया

मैंने इसे निम्नलिखित तरीके से तैयार किया है:

DROP    TABLE IF EXISTS `tbl_animal`; 
CREATE TABLE `tbl_animal` (
    id_animal       INTEGER     NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name            VARCHAR(25) NOT NULL DEFAULT "no name",
    specie          VARCHAR(10) NOT NULL DEFAULT "Other",
    sex             CHAR(1)     NOT NULL DEFAULT "M",
    size            VARCHAR(10) NOT NULL DEFAULT "Mini",
    edad            VARCHAR(10) NOT NULL DEFAULT "Lact",
    pelo            VARCHAR(5 ) NOT NULL DEFAULT "short",
    color           VARCHAR(25) NOT NULL DEFAULT "not defined",
    ra              VARCHAR(25) NOT NULL DEFAULT "not defined",
    CONSTRAINT `uc_Info_Animal` UNIQUE (`id_animal`)           
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


INSERT INTO `tbl_animal` VALUES (1,'no name', 'dog', 'M','Mini','Lact','Long','black','Bobtail');
INSERT INTO `tbl_animal` VALUES (2,'peluchin', 'cat', 'M','Mini','Lact','Long','white','not defined');
INSERT INTO `tbl_animal` VALUES (3,'asechin', 'cat', 'M','Mini','Lact','Corto','orange','not defined');

DROP    TABLE IF EXISTS `tbl_person`;  
CREATE TABLE `tbl_person` (
    type_person  VARCHAR(50) NOT NULL primary key        
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
INSERT INTO `tbl_person` (type_person) VALUES ('Worker');
INSERT INTO `tbl_person` (type_person) VALUES ('Civil');



DROP    TABLE IF EXISTS `tbl_worker`;  
CREATE TABLE `tbl_worker`(
    id_worker           INTEGER  NOT NULL PRIMARY KEY,
    type_person         VARCHAR(50) NOT NULL , 
    name_worker         VARCHAR(50) NOT NULL ,    
    address_worker      VARCHAR(40) NOT NULL DEFAULT "not defined",     
    delegation          VARCHAR(40) NOT NULL DEFAULT "not defined",
    FOREIGN KEY (type_person)               REFERENCES `tbl_person` (type_person),
    CONSTRAINT `uc_Info_worker` UNIQUE (`id_worker`)           
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

INSERT INTO `tbl_worker` VALUES (1,'Worker','N_CEDENTE1', 'DIR Worker 1', 'DEL');
INSERT INTO `tbl_worker` VALUES (2,'Worker','N_worker1', 'DIR Worker 2', 'DEL');
INSERT INTO `tbl_worker` VALUES (3,'Worker','N_worker2', 'address worker','delegation worker'); 


DROP    TABLE IF EXISTS `tbl_civil`; 
CREATE TABLE `tbl_civil`(
    id_civil                        INTEGER  NOT NULL PRIMARY KEY,
    type_person         VARCHAR(50) NOT NULL ,
    name_civil                      VARCHAR(50)  ,
    procedence_civil                VARCHAR(40)  NOT NULL DEFAULT "Socorrism",    
  FOREIGN KEY (type_person)             REFERENCES `tbl_person` (type_person),
    CONSTRAINT `uc_Info_civil` UNIQUE (`id_civil`)           
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


INSERT INTO `tbl_civil`  VALUES (1,'Civil','N_civil1' , 'Socorrism');


CREATE TABLE `tbl_event` (
    id_event     INTEGER NOT NULL,
    id_animal    INTEGER NOT NULL,
    type_person  VARCHAR(50) NOT NULL , 
    date_reception DATE DEFAULT '2000-01-01 01:01:01',
    FOREIGN KEY (id_animal)   REFERENCES `tbl_animal`    (id_animal),
    FOREIGN KEY (type_person )  REFERENCES `tbl_person`   (type_person ),
    CONSTRAINT `uc_Info_ficha_primer_ingreso` UNIQUE (`id_animal`,`id_event`)     
)ENGINE=InnoDB  DEFAULT CHARSET=utf8;

INSERT INTO `tbl_event` VALUES (1,1, 'Worker','2013-01-01 01:01:01' );
INSERT INTO `tbl_event` VALUES (2,2, 'Civil','2013-01-01 01:01:01' );

हालांकि, वहाँ एक तरीका है nulls से छुटकारा पाने के लिए?

मेरे पास जो प्रश्न हैं:

SELECT  a.*,b.*,z.*
FROM    tbl_event a
        left JOIN tbl_worker b
            ON a.type_person = b.type_person
        left JOIN tbl_animal z
            ON   z.id_animal = a.id_animal ;

SELECT  a.*,b.*,z.*
FROM    tbl_event a
        left JOIN tbl_civil b
            ON a.type_person = b.type_person
        left JOIN tbl_animal z
            ON   z.id_animal = a.id_animal ;

यहाँ एक अद्यतन sqlfiddle है


तालिका का उद्देश्य क्या है TYPE_PERSONजब इसमें केवल एक कॉलम होता है?
JW J

1
इसका अनुसरण करें: stackoverflow.com/questions/15128222/… ?

@cMinor - आप पूछ रहे हैं कि "उस नागरिक या कार्यकर्ता की आईडी कैसे पता चलेगी जिसने काम किया था?" क्या आप वास्तव में जानते हैं कि वास्तविक जीवन में काम किसने किया (या काल्पनिक है, अगर यह एक होमवर्क है)? क्या आपके पास पर्याप्त स्रोत डेटा है?

मुझे विरासत की आदत हो रही है, इसलिए मैंने एक टेबल पर्सन बनाया, जो लोगों के प्रकार (वर्कर, सिविल) को बनाए रखेगा, फिर ईवेंट टेबल में, किसी व्यक्ति को जॉब (सिविल या वर्कर) के आधार पर कैसे रेफर करें?
cMinor

1
मेरा मानना ​​है कि आपको डेटाबेस प्रशासकों में बेहतर सलाह
मिलेगी

जवाबों:


13

चूंकि मैंने आरेख बनाया है, इसलिए मैं बेहतर उत्तर देता हूं;)

वर्तमान संबंधपरक डेटाबेस दुर्भाग्य से सीधे विरासत का समर्थन नहीं करते हैं, इसलिए आपको इसे "सादे" तालिकाओं में बदलने की आवश्यकता है। ऐसा करने के लिए आम तौर पर 3 रणनीतियां होती हैं:

  1. NULL-सक्षम गैर-सामान्य फ़ील्ड के साथ एकल तालिका में सभी वर्ग 1
  2. अलग-अलग तालिकाओं में कंक्रीट कक्षाएं 2 । सार वर्ग के पास अपनी खुद की टेबल नहीं है।
  3. अलग-अलग टेबल में सभी कक्षाएं।

वास्तव में इसका क्या अर्थ है और कुछ पेशेवरों और विपक्षों के लिए, कृपया मेरे मूल पोस्ट में दिए गए लिंक देखें , लेकिन संक्षेप में (3) शायद आपका डिफ़ॉल्ट होना चाहिए जब तक कि आपके पास अन्य दो में से किसी एक के लिए विशिष्ट कारण न हो। आप डेटाबेस में इस तरह से (3) का प्रतिनिधित्व कर सकते हैं:

CREATE TABLE person (
    person_id int PRIMARY KEY
    -- Other fields...
);

CREATE TABLE civil (
    civil_id int PRIMARY KEY REFERENCES person (person_id)
    -- Other fields...
);

CREATE TABLE worker (
    worker_id int PRIMARY KEY REFERENCES person (person_id)
    -- Other fields...
);

CREATE TABLE event (
    event_id int PRIMARY KEY,
    person_id int REFERENCES person (person_id)
    -- Other fields...
);

दुर्भाग्य से, इस संरचना आप एक कराएंगे personकि है न civilहै और न ही worker(यानी आप अमूर्त वर्ग का दृष्टांत कर सकते हैं), और भी आप एक बनाने देगी personकि है दोनों civil और worker। डेटाबेस स्तर पर पूर्व को लागू करने के तरीके हैं , और एक डीबीएमएस में जो आस्थगित बाधाओं का समर्थन करता है 3 यहां तक ​​कि बाद को डेटाबेस में लागू किया जा सकता है, लेकिन यह उन कुछ मामलों में से एक है जहां एप्लिकेशन-स्तर की अखंडता का उपयोग वास्तव में बेहतर हो सकता है। ।


1 person , civilऔर workerइस मामले में।

2 civil और workerइस मामले में ( person"सार") है।

3 जो MySQL नहीं है।


डीबीएमएस में उत्तरार्द्ध को कैसे लागू किया जा सकता है जो स्थगित बाधाओं का समर्थन करता है? (एक व्यक्ति को दोनों होने से civilworker
रोकते हुए

@Gima कृपया उत्तर में मेरे द्वारा दिए गए लिंक का अनुसरण करें।
ब्रांको दिमित्रिजेविक

आप दावा करते हैं कि वर्तमान संबंधपरक डेटाबेस वंशानुक्रम का समर्थन नहीं करते हैं। Postgresql के बारे में क्या? postgresql.org/docs/9.6/static/ddl-inherit.html
क्लाइमेक्स

@ क्लीमैक्स मैं पोस्टग्रेक्यूएल से अवगत हूं, लेकिन इसका कार्यान्वयन केवल आंशिक है। आपके लिंक से: "अन्य प्रकार की बाधाएं (अद्वितीय, प्राथमिक कुंजी और विदेशी कुंजी बाधाएं) विरासत में नहीं मिली हैं।"
ब्रांको दिमित्रिजेविक

1
@naaz विदेशी कुंजी दोनों में मौजूद civilऔर worker। शायद आप शॉर्ट-हैंड सिंटैक्स से चूक गए (बस REFERENCESबिना FOREIGN KEY)?
ब्रांको दिमित्रिजेविक

5

अलग Civil_ID और Worker_ID की कोई आवश्यकता नहीं है; बस सभी तीन तालिकाओं के लिए कुंजी के रूप में व्यक्ति-आईडी का उपयोग करना जारी रखें: व्यक्ति, नागरिक और कार्यकर्ता। दो मान "सिविल" और "कार्यकर्ता" के साथ व्यक्ति के लिए एक कॉलम पर्सनेल्टी जोड़ें।

यह अब दो उप-वर्गों सिविलक्लास और एब्सट्रैक्ट बेस क्लास पर्सनक्लास के वर्करक्लास का प्रतिनिधित्व करता है। आपको एप्लिकेशन में ऑब्जेक्ट मॉडल के साथ DB में डेटा मॉडल के बीच एक अच्छा पत्राचार मिलता है।


मैंने एक sqlfiddle sqlfiddle.com/#/2/1f6a4/1 किया है, लेकिन मुझे नहीं पता कि अन्य तालिका में कैसे शामिल होना है, तो क्या आप कृपया अपना जवाब यहाँ sqlfiddle में बता सकते हैं?
cMinor

कोई "अलग" नहीं हैं - civil_idऔर worker_idवे एक ही चीज़ हैं person_id, जैसे कि अलग-अलग नाम हैं - FK1उनके सामने विदेशी (विदेशी कुंजी) मार्कर देखें।
ब्रांको दिमित्रिजेविक

4

आपका मामला वर्ग / उपवर्ग मॉडलिंग का एक उदाहरण है। या, जैसा कि आपने इसे ईआर, सामान्यीकरण / विशेषज्ञता में आरेखित किया है।

तीन तकनीकें हैं जो आपको इस मामले को कवर करने के लिए mysql तालिकाओं को डिजाइन करने में मदद करेंगी। उन्हें सिंगल टेबल इनहेरिटेंस, क्लास टेबल इनहेरिटेंस, और साझा प्राथमिक कुंजी कहा जाता है। आप एसओ में संबंधित टैग से जानकारी टैब में उन पर पढ़ सकते हैं।

/programming//tags/single-table-inheritance/info

/programming//tags/class-table-inheritance/info

/programming//tags/shared-primary-key/info

सिंगल टेबल इनहेरिटेंस सरल मामलों के लिए उपयोगी है जहां NULLs की उपस्थिति समस्याओं का कारण नहीं बनती है। अधिक जटिल मामलों के लिए कक्षा तालिका विरासत बेहतर है। साझा प्राथमिक कुंजी एक-से-एक संबंधों को लागू करने और जुड़ने में तेजी लाने के लिए एक अच्छा तरीका है।


1

आप एक व्यक्ति प्रकार की तालिका बना सकते हैं और सभी प्रकार के तालिकाओं के लिए एक फ़ील्ड जोड़ सकते हैं, जिसे टाइप प्रवर्तन की आवश्यकता होती है। फिर विदेशी कुंजियाँ बनाएँ। यहां एक उदाहरण आपके द्वारा प्राप्त किया जा रहा है ...

    CREATE TABLE person_type (
        person_type_id int PRIMARY KEY
        -- data: 1=civil, 2=worker
        -- Other fields (such as a label)...
    );

    CREATE TABLE person (
        person_id int PRIMARY KEY
        person_type_id int FOREIGN KEY REFERENCES person_type (person_type_id)
        -- Other fields...
    );

    CREATE TABLE civil (
        civil_id int PRIMARY KEY REFERENCES person (person_id)
        person_type_id int FOREIGN KEY REFERENCES person (person_type_id)
        -- Other fields...
    );

    CREATE TABLE worker (
        worker_id int PRIMARY KEY REFERENCES person (person_id)
        person_type_id int FOREIGN KEY REFERENCES person (person_type_id)
        -- Other fields...
    );

    CREATE TABLE event (
        event_id int PRIMARY KEY,
        person_id int REFERENCES person (person_id)
        -- Type is optional here, but you could enforce event for a particular type
        person_type_id int FOREIGN KEY REFERENCES person (person_type_id)
        -- Other fields...
    );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.