MySQL布尔类型

4
我在这个问题上真的很犹豫该怎么做。过去十年我一直忍受着这个问题,但我认为现在是时候决定正确的处理方式了。
根据互联网信息,MySQL不支持本机数据类型,这就解释了为什么每当我选择"BOOLEAN"时,列最终会变成tinyint(1)。
我无论如何都不介意将数据存储为带有1或0值的tinyint,但是我对这样一个事实有问题:当我从数据库中选择许多行,并且这一列中出现字符串"1"或"0"而不是PHP本机bool true/false。当然,PHP仍然可以将此变量视为布尔值进行处理,因为它似乎自动知道我想做什么,无论我是否执行== 0、== 1甚至== '0'或== '1'(如果我真的感觉要这样做)时。
因此,我让PHP的json_encode函数来处理这些数据,并在我的Backbone/Handlebars实现进行ajax调用时输出它,得到了一个非常漂亮的JSON对象(通常包含许多行的数据),其中包括以下内容:{"myVariable":"1"}或者{"myVariable":"0"}
我相信你能看到在Handlebars.js中想要做一些像这样的事情的问题。
{{#if myVariable}} 
    Do this
{{else}}
    Do that
{{/if}}

现在,我真正不想做的事情是像这样:

<?php
for($i = 0; $i < count($recordSet); $i++) {
    $recordSet[$i]['myVariable'] = (bool)$recordSet[$i]['myVariable'];
}
?>

由于我正在构建的应用程序在数据库中有成千上万的列,我不能(或者只应该需要)为我想要在我的JavaScript中像布尔值一样运行的每个列运行上述代码。而且我真的不想这样做(尽管这可能是最容易的方法)。

Handlebars.registerHelper('ifTrue', function(a, b) {
    // Cast the compared value to a bool and then run a regular handlebars #if statement
});

有更好的方法吗?我正在使用CodeIgniter...是否可以以某种方式修改数据库类,以便检测tinyint(1)列并自动将其转换为布尔值,然后只需这样做,直到MySQL支持真正的布尔列?我知道他们正在计划,但是...


2
https://dev59.com/SnVC5IYBdhLWcg3wcwwm#289759 - David Starkey
这是一个很好的解决方案,用于确定使用哪种数据类型,但它并没有完全回答如何高效地从查询中获取纯PHP的true/false值,它更多地概述了哪些数据类型存储该值。无论我使用BIT还是tinyint(1),当将查询结果通过json_encode运行时,仍然存在相同的问题,即返回一个字符串“1”或“0”。 - Benjamin Oman
1
选择 <列名>,CASE blnColumn WHEN '0' THEN 'FALSE' WHEN '1' THEN 'TRUE' - http://www.dreamincode.net/forums/topic/296164-forget-how-to-convert-bit-to-truefalse/ - David Starkey
否则,你可以在客户端把 myVariable 强制转换成数字。就像这样:{{#if +myVariable}}。 - Elad
tinyint(1)对于您的目的应该可以很好地工作。只要在客户端正确解码json对象,它就可以与PHP和javascript的true/false语法一起使用(有关零和js的更多信息:https://dev59.com/s2sz5IYBdhLWcg3w3bpb)。 - Michael Krikorev
1个回答

1
请记住,默认情况下,PHP/MySQL驱动程序返回的列值只是字符串(即未经类型化的字节数组)。以下简短代码片段演示了此情况:
// mysqli driver
$c = mysqli_connect ($host, $user, $pass, $dbname);
$r = mysqli_query($c, 'SELECT * FROM foo');
$f = mysqli_fetch_array($r);
foreach ($f as $k => $v) {
    echo "$k => $v [" . gettype($v) . ']' . PHP_EOL;
}

// PDO
$c = new PDO("mysql:dbname=$dbname;host=$host", $user, $pass);
$r = $c->query('SELECT * FROM foo');
$f = $r->fetch();
foreach ($f as $k => $v) {
    echo "$k => $v [" . gettype($v) . ']' . PHP_EOL;
}

“默认情况下”,因为可以提供映射给驱动程序,使其将这些字符串转换为本机PHP类型。为此,mysqli 具有 mysqli_result::fetch_object()PDO 具有 PDOStatement::fetchObject()

虽然可能从元数据甚至表定义中检索实际列类型,但在典型情况下,客户端应用程序事先知道它。

最重要的是:您确实希望执行此操作(或类似操作):

$recordSet[$i]['myBoolColumn'] = (bool)$recordSet[$i]['myBoolColumn'];

因为实际上你也应该这样做:

...

$recordSet[$i]['myIntColumn'] = (int)$recordSet[$i]['myIntColumn'];

但是由于PHP在类型方面非常宽松,所以我不会太担心这个问题。


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