【问题标题】:MySQL custom global defined variableMySQL自定义全局定义变量
【发布时间】:2013-03-13 09:30:32
【问题描述】:

在我的数据库设计中,我倾向于将一些用作 ROLE 或 TYPE 的变量存储为 SMALLINT

例如:

CREATE TABLE `house` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `type` smallint(11) NOT NULL,

在 PHP 中,我会这样做:

define('HOUSE_SMALL_TYPE', '0');
define('HOUSE_MEDIUM_TYPE', '1');

所以在 PHP 中,我在 SELECT 查询中:

$this->db->query("SELECT * FROM house  
                  WHERE type = ?;", HOUSE_SMALL_TYPE);

我的问题是:
  1. 在 PHP 部分,有没有更好的方法来做到这一点?
  2. 在 MySQL 本身中,MySQL 是否也具有全局定义功能(如 PHP 中的定义)?

我也想做点什么

SELECT * FROM house  WHERE type = HOUSE_SMALL_TYPE;

在 MySQL 查询中。

我的目的是,当我在 MySQL 中执行 SELECT 时,我不会继续将值 0、1、2 与其真正含义进行映射。只是方便查看表值,无需更改结构表和字段。

【问题讨论】:

  • 我想你在找ENUM
  • 定义“更好的方式”的标准。您到底想改进什么?
  • @Rikesh 意味着我必须使用 ENUM 更改我的数据库类型,对吗?我的表有些已创建,但我会在下一个创建表时考虑到这一点。
  • @HendryH。您也可以阅读我链接的帖子。你的问题很模糊,所以如果你看起来像比使用它。
  • @Your Common Sense 实际上,我只是好奇你们是如何在 php 中做到这一点的。我考虑任何替代方案,因为我仍处于早期开发阶段。

标签: php mysql database


【解决方案1】:

自 MySQL 5.5 起,无法设置全局用户定义变量。

一种解决方法可能是创建一个存储过程来返回您需要的内容。

DROP PROCEDURE IF EXISTS HOUSE_SMALL_TYPE;
DELIMITER //
CREATE PROCEDURE HOUSE_SMALL_TYPE ()
BEGIN 
SELECT 0;
END//
DELIMITER ;

然后调用它。

CALL HOUSE_SMALL_TYPE();

需要DROP 语句才能对其进行修改。

【讨论】:

    【解决方案2】:

    恕我直言,MySQL 在这方面有很大的差距,显然是在后面的版本中。一种替代方法可能是求助于设置操作系统环境变量,但如何从 MySQL 中检索这些值,我一直无法看到。

    这里有一整页:https://dev.mysql.com/doc/refman/5.0/en/setting-environment-variables.html 教我们如何在 shell 中“设置”操作系统环境变量,但没有在 MySQL 中实际调用这些变量。

    作为另一种解决方法,使用 FUNCTION 可能被认为比 STORED PROCEDURE 更轻量级,如下所示:

    CREATE DEFINER=`root`@`localhost` FUNCTION `DEFAULT_COUNTRY_CODE`() RETURNS CHAR(4)
    DETERMINISTIC
    RETURN '+234';
    

    在查询的其他地方,您可以这样做:

    SELECT CONCAT(DEFAULT_COUNTRY_CODE(), "-", telephone) FROM contacts WHERE CountryCode = "NGA"
    

    【讨论】:

    • 看来MySQL无法访问环境变量。正如他们所说的Environment variables can be set at the command prompt to affect the current invocation of your command processor...,就是这样。
    【解决方案3】:

    您的方法很好,如果您想查看 MySQL 中的值而不是 1、2、3 等,请考虑:

    define('HOUSE_SMALL_TYPE', 'HOUSE_SMALL_TYPE');
    define('HOUSE_MEDIUM_TYPE', 'HOUSE_MEDIUM_TYPE');
    

    然后在 MySQL 中你可以使用:

    SELECT * FROM house  WHERE type = 'HOUSE_SMALL_TYPE';
    

    您只需要记住,您不能在没有 PHP 支持的情况下将任何您喜欢的值塞入 house.type。

    最好考虑一下:

    class HouseType {
      const SMALL = 'SMALL';
      const MEDIUM = 'MEDIUM';
    }
    

    class House {
      const TYPE_SMALL = 'SMALL';
      const TYPE_MEDIUM = 'MEDIUM';
    }
    

    因为您可以在 PHP 代码中使用 HouseType::SMALLHouse::TYPE_SMALL 而不是使用全局定义。通过这样做,您可能会受益于某些 IDE 中的代码完成。

    【讨论】:

      【解决方案4】:

      自 MySQL 5.5 以来,无法设置全局用户定义变量,另一种解决方法可能是帮助表,例如

      create table glob_var(key varchar(10) unique not null, val varchar(10) not null);
      

      【讨论】:

        【解决方案5】:

        我建议使用 MySQL 变量:

        SET HOUSE_SMALL_TYPE = 0;
        SET HOUSE_MEDIUM_TYPE = 1;
        

        然后,您可以在查询中使用这些变量:

        SELECT * FROM house  WHERE type = @HOUSE_SMALL_TYPE;
        

        这个方法定义了session变量:

        如果您更改会话系统变量,该值仍然有效 直到您的会话结束或直到您将变量更改为 不同的价值。其他客户端看不到更改。

        如果要定义全局 MySQL 变量(适用于所有会话):

        SET GLOBAL HOUSE_SMALL_TYPE = 0;
        SET GLOBAL HOUSE_MEDIUM_TYPE = 1;
        

        要明确指出变量是全局变量,请在前面加上 它的名称由 GLOBAL 或 @@global.. 超级权限是必需的 设置全局变量。

        文档:
        SET statement
        Using system variables
        User-defined variables

        【讨论】:

        • 啊哈..这正是我想要的。我在 HOUSE_SMALL_TYPE 前面添加了 @ 以使其正常工作。
        • MySQL 不允许全局用户变量,只允许全局用户变量。来自MySQL SET statement reference:“[GLOBAL | SESSION] system_var_name = expr”。在您上面的答案中, SET GLOBAL HOUSE_SMALL_TYPE = 0;在 MySQL 5.5 上对我来说失败并显示“未知系统变量‘HOUSE_SMALL_TYPE’”消息。
        • “Hari 的”评论应读作:MySQL doesn't allow global user variables, only user variables
        猜你喜欢
        • 1970-01-01
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 2020-04-04
        • 2014-05-12
        • 2019-04-08
        相关资源
        最近更新 更多