【问题标题】:Storing an array of unknown length存储未知长度的数组
【发布时间】:2019-12-01 08:33:51
【问题描述】:

我让我的用户在 HTML 表单中添加数字输入并用值填充它们。表单在提交时被序列化并发送到 PHP 文件,该文件将数据插入到带有 PDO 的 MySQL 数据库中。数据库表有一堆列用于存储表单中的其他值,但用于存储用户添加输入的列设置如下:

input_value_1
input_value_2
input_value_3
input_value_4
...
...
input_value_10

这些列允许NULL,因为我不知道用户是否会添加任何数字输入。

有没有更好的方法来存储这些数字?

下面是我的 JS 的一部分,用于获取表单数据并发送到 LandOwners.php,它将值插入到我的数据库中。代码没有数字输入(我还没有添加它们,因为我不确定应该如何存储它们的数据)。

$("#createLandOwnerForm").on( "submit", function( event ) {
    event.preventDefault();

    createLandOwner($(this).serialize(), appendCreatedLandOwnerToSelect, appendCreatedLandOwnerToSelect_Error);

    $('#createLandOwnerForm')[0].reset();
});

function createLandOwner(landOwner, onSuccess, onError) {    
     var data = landOwner + "&action=create";

     $.ajax({
        type: "post",
        url: host + 'LandOwners.php',
        data: data,
        success: onSuccess,
        error: onError
     });
}

下面是 LandOwners.php 的一部分,它插入到我的数据库没有数字输入(我还没有添加它们,因为我不确定我应该如何/如果应该)。

$stmt = $pdo->prepare("INSERT INTO land_owner (land_owner_name, land_owner_identification_number, land_owner_contact, land_owner_phone, land_owner_email, land_contracts) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$land_owner_name, $land_owner_identification_number, $land_owner_contact, $land_owner_phone, $land_owner_email, $land_contracts]);

$last_inserted_land_owner_id = $pdo->lastInsertId();

$stmt = $pdo->prepare("SELECT * FROM land_owner WHERE land_owner_id = ?");
$stmt->execute([$last_inserted_land_owner_id]);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $arr[] = $row;
}

if(!$arr) exit('No rows');

echo json_encode($arr);

$stmt = null;

下面是从我的数据库中选择数据的 LandOwners.php 部分。我想(仍然能够)得到 JSON 格式的结果。

$arr = [];

if (isset($_POST["land_owner_id"])){
  $stmt = $pdo->prepare("SELECT * FROM land_owner WHERE land_owner_id = ?");
  $stmt->execute([$land_owner_id]);
} else {
    $stmt = $pdo->prepare("SELECT * FROM land_owner");
    $stmt->execute();
}

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  $arr[] = $row;
}

if(!$arr) exit('No rows');

echo json_encode($arr);

$stmt = null;
break;

【问题讨论】:

  • 是的,你应该有一个表,其中包含值和与它们相关的任何内容的关系 - 更简单的行而不是许多重复的列更好。
  • @Qirel 所以我应该用一个名为input_values 的新列替换这十列,并将其与具有外键的新表相关联?如果这是正确的,如果有人添加了 15 个输入,input_values 应该是什么样子?新表应该如何构建?谢谢!
  • @Qirel 我已经用我的正确代码更新了我的问题。应该怎么改?
  • 创建一个 land_owner_input 并将其中的所有输入放在单独的行中,并引用 land_owner 的唯一标识符(可能是 ID)。
  • 看起来很棒!这样一来,您就可以为每个 land_owner 提供无限的、未指定数量的输入。

标签: php mysql sql arrays serialization


【解决方案1】:

如果您发现自己的桌面上开始出现column1column2 - 很有可能您的设计存在缺陷,您应该创建一个单独的表格 - 每个columnX 都有一个自己的行。如果您发现自己在同一个表上有多个重复列,那么(几乎)最好有一个单独的表。

这样,您可以避免将逗号分隔的值存储在列中,如果您突然必须引入另一个值 column{X+1},您可以避免破坏您的代码/查询 - 而是可以根据需要拥有尽可能多或尽可能少的输入值到。

对您而言,这类似于一个名为 land_owner_input 的新表,其中您有值(您将放入 columnX),以及对 land_owner 中该值所属行的引用.

典型的设计模式是这样的。

CREATE TABLE land_owner_input (
    land_owner_input_id INT(11) AUTO_INCREMENT
    land_owner_id INT(11), 
    land_owner_input_value VARCHAR(MAX)
);

请记住,您在新表中的land_owner_id 的类型和大小应与其引用的 ID 完全相同。

您还可以在land_owner_idland_owner 表的ID 之间创建外键约束,以确保数据完整性。

一旦您有了新表,您可以使用LEFT JOIN(如果您只想返回具有输入值的行,则使用普通的JOIN)一起查询它们。

SELECT *
FROM land_owner AS lo
LEFT JOIN land_owner_input AS loi
    ON loi.land_owner_id = lo.land_owner_id 

【讨论】:

  • 感谢您的回答,非常感谢您的时间和帮助!
  • 我正在使用您的解决方案来存储我的数据,但我已经为一个与之相关的问题苦苦挣扎了好几个小时。你能看看吗? stackoverflow.com/q/57209240/1711950
【解决方案2】:

也许你冷有一个列,json类型,并在里面存储json?

类似:

CREATE TABLE IF NOT EXISTS some_table
(
  `json` JSON NOT NULL
  ) COLLATE='utf8_general_ci' ENGINE=InnoDB;

您可以将 JSON 存储到此列,例如:

{"input_value_1":1, "input_value_2",...."input_value_10":10}

您可以使用 JSON_EXTRACT 轻松获得单个值(假设它们始终具有相同的键):

SELECT JSON_EXTRACT(json,'$.input_value_'.$x) FROM some_table WHERE some_condition

【讨论】:

  • 我已经用我的当前代码更新了我的问题。应该怎么改?
猜你喜欢
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多