MySQL自定义全局变量定义

4

在我的数据库设计中,我倾向于将一些用作角色或类型的变量存储为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中的define)?

我还想做类似的事情。

SELECT * FROM house  WHERE type = HOUSE_SMALL_TYPE;

在MySQL查询中。

我的目的是,在MySQL中进行SELECT时,我不想一直将值0、1、2与其真正含义进行映射。这只是为了方便查看表的值,而不改变表和字段的结构。


2
我认为你正在寻找ENUM - Rikesh
1
为“更好的方式”定义一个标准。你想要改进什么? - Your Common Sense
@Rikesh的意思是我需要使用ENUM来更改我的数据库类型,对吧?我的一些表已经创建了,但我会在下一个创建表时考虑这个问题。 - Hendry H.
@HendryH。您可以阅读我链接的帖子。您的问题比较模糊,如果您需要类似的东西,请使用它。 - Rikesh
@你的常识,实际上,我只是好奇你们在php中是如何做到的。考虑到我还处于早期开发阶段,我会考虑任何替代方案。 - Hendry H.
5个回答

4

自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无法访问环境变量。正如他们所说:“环境变量可以在命令提示符下设置,以影响当前调用您的命令处理器...”,就是这样。 - lepe

0

自 MySQL 5.5 起,无法设置全局用户定义变量,另一种解决方法可以使用辅助表。

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

0

你的方法很好,如果你想在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中受益于代码完成。


-2

我建议使用MySQL变量:

SET HOUSE_SMALL_TYPE = 0;
SET HOUSE_MEDIUM_TYPE = 1;

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

SELECT * FROM house  WHERE type = @HOUSE_SMALL_TYPE;

该方法定义了会话变量:

如果您更改了会话系统变量,则该值将保持有效,直到您的会话结束或者您将变量更改为其他值。该更改对其他客户端不可见。

如果您想定义全局MySQL变量(对所有会话都可用):

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

为了明确表示一个变量是全局变量,可以在其名称前加上GLOBAL或@@global。设置全局变量需要SUPER特权。
文档: SET语句 使用系统变量 用户定义变量

啊哈..这正是我想要的。在 HOUSE_SMALL_TYPE 前面加上 @ 就可以让它工作了。 - Hendry H.
9
MySQL不允许使用全局用户变量,只有全局系统变量。参考MySQL SET语句文档:"[GLOBAL | SESSION] system_var_name = expr"。在你上面的答案中,使用"SET GLOBAL HOUSE_SMALL_TYPE = 0;"会在MySQL 5.5上失败,并显示一个"UNKNOWN SYSTEM VARIABLE 'HOUSE_SMALL_TYPE'"的错误信息。 - Hari
9
“Hari的”评论应该被理解为:“MySQL不允许全局用户变量,只允许用户变量”。 - lepe
或者应该这样理解:MySQL不允许全局用户变量,只允许全局系统变量。 - EzPizza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接