سؤال

أولاً، اسمحوا لي أن أستهل هذا السؤال بالقول إنني مصمم بيانات سيئ للغاية.أنا أعرف ما يكفي فقط لأكون خطيرًا.

يحتوي الجدول الذي أقوم بإنشائه على أربعة مفاتيح خارجية، اثنان منها يشيران إلى نفس الجدول.إليك بيان الإنشاء لهذا الجدول.

CREATE  TABLE IF NOT EXISTS `abnr`.`reputation_event_log` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `reputation_event_id` INT NULL ,
  `giver_user_id` INT NULL ,
  `receiver_user_id` INT NULL ,
  `review_id` INT NULL ,
  `giver_point_value` SMALLINT NULL DEFAULT 0 ,
  `receiver_point_value` SMALLINT NULL DEFAULT 0 ,
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_reputation_log_user` (`giver_user_id` ASC) ,
  INDEX `fk_reputation_log_user1` (`receiver_user_id` ASC) ,
  INDEX `fk_reputation_log_review` (`review_id` ASC) ,
  INDEX `fk_reputation_log_reputation_event` (`reputation_event_id` ASC) ,
  CONSTRAINT `fk_reputation_log_user`
    FOREIGN KEY (`giver_user_id` )
    REFERENCES `abnr`.`user` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_user1`
    FOREIGN KEY (`receiver_user_id` )
    REFERENCES `abnr`.`user` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_review`
    FOREIGN KEY (`review_id` )
    REFERENCES `abnr`.`review` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reputation_log_reputation_event`
    FOREIGN KEY (`reputation_event_id` )
    REFERENCES `abnr`.`reputation_event` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;

الفهارس التي أهتم بها لهذا المنشور هي fk_reputation_log_user و fk_reputation_log_user1.كل حدث يتعلق بالسمعة له مانح، لكن بعضها فقط لديه متلقي.أود يحب هذا FK لاغٍ، لكنني لا أعرف كيفية القيام بذلك، أو حتى إذا كان "مسموحًا به".

لقد فكرت أيضًا في جعل جميع أعمدة FK جزءًا من المفتاح الأساسي للحصول على حماية على مستوى قاعدة البيانات ضد إدخالات السجل المكررة - لكن هذا لن ينجح نظرًا لأن أعمدة PK يجب أن تكون غير فارغة.

إذا كنت بحاجة إلى مزيد من التفاصيل، يرجى ذكر ذلك في التعليقات.شكرًا!

(نعم، هذا لنظام السمعة الذي لا يختلف كثيرًا عن نظام SO)

هل كانت مفيدة؟

المحلول

CREATE  TABLE IF NOT EXISTS `abnr`.`reputation_event_log` (
  `id`                  INT NOT NULL AUTO_INCREMENT ,
  `reputation_event_id` INT NULL ,
  `giver_user_id`       INT NOT NULL , -- mandatory giver_user_id
  `receiver_user_id`    INT NULL ,     -- optional receiver_user_id
  . . .

نعم، يمكنك الحصول عليه NULL في عمود تم الإعلان عن قيد المفتاح الخارجي عليه.ال NOT NULL يكون القيد الموجود على عمود مستقلاً عن أي قيود (قيود) للمفاتيح الخارجية في هذا العمود.

المفتاح الخارجي يعني ذلك لو يحتوي العمود على قيمة غير فارغة، فيجب أن تكون هذه القيمة موجودة في المفتاح الأساسي للجدول المشار إليه بواسطة قيد المفتاح الخارجي.

يحرر: أما بالنسبة لك UNIQUE الشرط، هل أنت على علم أنه يمكنك الإعلان عن UNIQUE القيد على الأعمدة الفارغة.العمود يمكن يحتوي NULLs (على عكس قيد المفتاح الأساسي).هذا هو سلوك SQL القياسي، ويدعمه MySQL.

  . . .
  PRIMARY KEY (`id`),
  CONSTRAINT UNIQUE (`giver_user_id`, `receiver_user_id`, 
                     `review_id`, `reputation_event_id`),
  . . .
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top