0

私のサイトは、一般ユーザーとビジネス ユーザーとスーパー管理者の 2 種類のユーザーで構成されています。それらはすべてユーザー テーブル (名前、電子メール、パスワード) にリストされ、ビジネス ユーザーのビジネスのみの関連情報 (ビジネスの種類、住所など) を保持する busines_users テーブルが追加されます。

そして、サイトのメールを保持する 3 番目のテーブルがあります。通常のユーザーから business_users または super_admins (サポートなど) に送信されるメール。

そのため、このメール テーブルには 2 つの列 (from、to) があり、userID 列を参照する場所は users テーブルです。ここに問題があります。business_user が自分のアカウントを削除したとします。彼が送信したメールも削除するつもりです (通常のユーザーまたはスーパー管理者に向けられているかどうかに関係なく) 問題は、mails テーブルの構造が避けられないことです。上記のメールを削除すると、super_admin の正規ユーザーが HIM に送信したメールも削除されます。

調査された 2 つのシナリオがあります。

  1. メールをまったく削除しないでください。その場合、議論はここで終わります。
  2. 彼に送信されたメールが削除されないようにデータベースを再設計します (reg_users の画面にはまだメールが表示されます) が、彼が送信したメールは削除されます。

あなたは何を提案しますか?2番目のオプションを使用する場合、データベースをどのように設計する必要がありますか。ここに3つのテーブルがあります:

CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`users` (
`user_ID` INT(11) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NOT NULL ,
`lastname` VARCHAR(45) NOT NULL ,
`email` VARCHAR(255) NULL DEFAULT NULL ,
`password` VARCHAR(100) NULL DEFAULT NULL ,
`hash` VARCHAR(32) NULL DEFAULT NULL ,
`usertype` ENUM('1','2','3','4') NULL DEFAULT NULL ,
 PRIMARY KEY (`user_ID`) ,
 INDEX `fk_users_usertype1_idx` (`usertype` ASC) ,
 CONSTRAINT `fk_users_usertype1`
 FOREIGN KEY (`usertype` )
 REFERENCES `alternative_appointm`.`usertype` (`type_id` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8

CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`business_users` (
`crID` INT(11) NOT NULL ,
`address` VARCHAR(45) NULL DEFAULT NULL ,
`url` VARCHAR(45) NULL DEFAULT NULL ,
`phone` VARCHAR(20) NULL ,
`city` VARCHAR(100) NULL ,
`municipality` VARCHAR(100) NULL ,
`bus_user_type` ENUM('1','2','3','4','5') CHARACTER SET 'latin1' NULL ,
 PRIMARY KEY (`crID`) ,
 INDEX `fk_business_users_buz_usertype1_idx` (`bus_user_type` ASC) ,
 INDEX `crID` (`crID` ASC) ,
 CONSTRAINT `fk_business_users_buz_usertype1`
 FOREIGN KEY (`bus_user_type` )
 REFERENCES `alternative_appointm`.`buz_usertype` (`Type_id` )
 ON DELETE CASCADE
 ON UPDATE CASCADE,
 CONSTRAINT `fk_business_users_users1`
 FOREIGN KEY (`crID` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE CASCADE
 ON UPDATE CASCADE)
 ENGINE = InnoDB
 DEFAULT CHARACTER SET = utf8


CREATE  TABLE IF NOT EXISTS `alternative_appointm`.`mails` (
`message-iD` INT(10) NOT NULL AUTO_INCREMENT ,
`from` INT(11) NULL DEFAULT NULL ,
`to` INT(11) NULL DEFAULT NULL ,
`datetime` DATETIME NULL DEFAULT NULL ,
`subject` TEXT NULL DEFAULT NULL ,
`message` TEXT NULL DEFAULT NULL ,
 PRIMARY KEY (`message-iD`) ,
 UNIQUE INDEX `message-iD_UNIQUE` (`message-iD` ASC) ,
 INDEX `fk_mails_users1_idx` (`from` ASC) ,
 INDEX `fk_mails_users2_idx` (`to` ASC) ,
 CONSTRAINT `fk_mails_users1`
 FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION,
 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)
 ENGINE = InnoDB
 DEFAULT CHARACTER SET = utf8
4

1 に答える 1

1

テーブルalternative_appointm.mails上 整合性制約が必要です。現在:

CONSTRAINT `fk_mails_users1`
FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION,

 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)

最初のステップは を追加することです。ほとんどの制約でこれを行う必要があります。つまり、ユーザー ID を更新すると、または列'ON UPDATE CASCADE'で直接更新されます。fromto

次に、テーブルでユーザーが削除されたときに、users受信したメールではなく、送信したすべてのメールを削除する必要があります。そのため、列にユーザー ID があるメールのみを削除する必要がありfromます。

したがって、最初の制約を更新し'to'ます。列に関する制約ではなく、この制約のみを更新します。

CONSTRAINT `fk_mails_users1`
FOREIGN KEY (`from` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE CASCADE
 ON UPDATE CASCADE,

2 番目の制約は、一部のデータが削除したいユーザー ID を参照している場合、ユーザーの削除を防ぎます。削除を許可するには、フィールドを空にする必要があります (NO ACTIONは と同じですRESTRICT) この制約を使用して:

 CONSTRAINT `fk_mails_users2`
 FOREIGN KEY (`to` )
 REFERENCES `alternative_appointm`.`users` (`user_ID` )
 ON DELETE SET NULL
 ON UPDATE CASCADE)

作業削除が行われ、このユーザーに送信されたメールはまだテーブルにありますが、「to」列にこのユーザーの ID がありません (この ID はもう存在しません)。トランザクションを使用して、影響を受ける行を変更し、デフォルトの「削除されたユーザー」ユーザー アカウント ID のような特別な ID を「to」列に設定できます。postgreSQl では「ON DELETE SET DEFAULT」がありますが、これは MySQL AFAIK には存在しません。

于 2013-09-09T11:48:16.397 に答える