努力弄清楚如何设置这些约束

时间:2018-08-09 19:55:04

标签: mysql database

我当前正在设置一些必须使用某些约束的不同表。我一直没事,但我坚持以下几点:

  • 将“国家/地区”列限制为英国,美国和澳大利亚之间的选择
  • 创建“ ImageFilename”列,以便每条记录都必须具有.JPG扩展名

这些示例是否有特定的约束条件?或者是在这里跳槽思维的情况?我试图思考使用已知的当前约束的方法,但是我很沮丧。

任何帮助将不胜感激!预先感谢。

编辑:可能是CHECK约束吗?

2 个答案:

答案 0 :(得分:0)

从MySQL 8.0开始,MySQL doesn't support CHECK constraints.

即使MySQL要添加对CHECK约束的支持,我也不会将其用作解决方案,因为当您最终添加新西兰和加拿大时,或者如果您除了.JPG之外还支持.PNG,您将拥有重新定义约束条件。

对于国家/地区,我将创建一个查找表和一个外键约束来限制您的国家/地区列。

CREATE TABLE Countries ( Country VARCHAR(75) PRIMARY KEY );

ALTER TABLE DifferentTable ADD FOREIGN KEY (Country) REFERENCES Countries(Country);

这使您只需在国家表中插入新的国家名称即可支持新国家。

对于图像扩展,我可以想到两种选择:

  1. 定义一个触发器,如果​​文件名与正确的扩展名不匹配,该触发器将引发SIGNAL

    CREATE TRIGGER ImageFilenameIns BEFORE INSERT ON DifferentTable
    FOR EACH ROW
    BEGIN
      IF (SUBSTRING_INDEX(NEW.ImageFilename, -1) <> '.JPG') THEN
        SIGNAL SQLSTATE '45000'
          SET MESSAGE_TEXT = 'You must use a .JPG filename';
      END IF;
    END
    
    CREATE TRIGGER ImageFilenameUpd BEFORE UPDATE ON DifferentTable
    FOR EACH ROW
    BEGIN
      IF (SUBSTRING_INDEX(NEW.ImageFilename, -1) <> '.JPG') THEN
        SIGNAL SQLSTATE '45000'
          SET MESSAGE_TEXT = 'You must use a .JPG filename';
      END IF;
    END
    

    如果您使用mysql客户端或SQL脚本创建此触发器,请记住要设置DELIMITER

    如果您有朝一日想支持.PNG或其他扩展名,则使用触发器解决方案需要重新定义触发器。

  2. 定义一个generated column来表示文件扩展名,并确保引用允许的文件扩展名的查找表。

    CREATE TABLE ImageFileExtensions ( Extension VARCHAR(3) PRIMARY KEY );
    INSERT INTO ImageFileExtensions (Extension) VALUES ('JPG');
    
    ALTER TABLE DifferentTable
      ADD COLUMN ImageFilenameExtension VARCHAR(3) AS (SUBSTRING_INDEX(ImageFilename, -1)) STORED,
      ADD FOREIGN KEY(ImageFilenameExtension) REFERENCES ImageFileExtensions(Extension);
    

    使用后一种解决方案,您只需在ImageFileExtensions表中插入新扩展名即可添加对新文件扩展名的支持。

答案 1 :(得分:0)

我不确定您尝试什么,但是可以在mysql中使用IF: *(用于创建):

CREATE TABLE IF NOT EXISTS
:row(row_id varchar(8) NOT NULL, 
:country varchar(25) NOT NULL CHECK (country IN ('USA','UK','Australia')),
PRIMARY KEY (row_id));

测试两个字符串是否相同,如果相同则返回“ YES”,否则返回“ NO”(用于选择):

SELECT IF(STRCMP(":country","UK") = 0, "YES", "NO");

或:

SELECT :row, CASE :Country
WHEN 'USA' THEN 1
WHEN 'UK' THEN 2
WHEN 'Australia' THEN 3
ELSE 'NO'
      END AS :row1, :row2, :row3
FROM :Table

但是仍然可以使用PHP执行相同的操作:

$country = $_GET['country'];
switch($country){
case "UK":
case "USA":
case "Australia":
   Model::DB->Post($country, "Country");
   break;
default:
   App::Error->Err("Invalid input - " . $country);
}