我正在做一个社交网络的迷你项目,我对桌子有疑问。 让我们看看,我需要在他们的页面中提供帖子。要做到这一点,我是否必须为每个用户创建表,或者只创建一个表并将其用于多个用户(可以通过选择特定用户名并在其页面中显示数据来获取数据)。 哪种方式最好? 我的PHP代码:
<?php
$query="select * from table_name where user=$username order by time desc;";
?>
答案 0 :(得分:3)
最好只使用1个用户表,并为您的帖子分别设置。您的users表应具有每个特定用户的所有信息,其中包含由MySQL数据库自动生成的1个唯一值。 (使用自动增量)在posts
表中,您应该拥有每个帖子的所有数据,其中user_id
列保存来自users表的唯一值,这样您就知道是谁发布了它。
这是一个模型表结构:
Users table:
uid | name | email
Posts table:
uid | user_id | message
posts表中的 user_id
应始终等于users表中的某些uid
。
每个表都应该始终具有一些赋予其主要值的唯一值
我非常关心您的应用程序的安全性。准备好的陈述更容易使用,而且更安全。
在您分享的代码段中:
<?php
$query="select * from table_name where user=$username order by time desc;";
?>
这个查询非常不安全,正如Bobby Tables会告诉你的那样。我不确定您使用的数据库连接类型,但我建议PDO
。我写了一个函数,使这非常容易,这是它的代码片段:
这是我通常称为connection.php
的文件,您可以在需要使用数据库的任何页面上导入该文件。
<?php
$host = 'localhost';
$db = '';
$user = '';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host={$host};dbname={$db};charset={$charset}";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $user, $pass, $opt);
function pdoQuery($query, $values = []) {
global $pdo;
if(!empty($values)) {
$stmt = $con->prepare($query);
$stmt->execute($values);
} else {
$stmt = $con->query($query);
}
return $stmt;
}
?>
此函数允许您轻松使用预准备语句 包括connection.php页面和以一种方式编写查询 可读,清洁和安全。我确信很多读这篇文章的人不习惯准备陈述或知道如何 工作,这篇文章的其余部分将解释这一点。
这里最大的区别之一是,而不是使用String Interpolation 您的查询,您将变量设置为问号
?
,所以您的 查询看起来像这样:UPDATE table SET user=?
而不是UPDATE table SET user='$user'
- 变量将在稍后发送 安全,所以这可以防止SQL注入。
这就是你的查询现在的样子:
pdoQuery("SELECT * FROM `table_name` WHERE user=? ORDER BY `time` DESC", [$username]);
这基本上是它的工作原理:
pdoQuery(string $query, array $variables)
如果没有传递变量,它会自动使用query()
函数,如果你传递变量,它会自动绑定并执行语句。无论您执行什么查询,该函数始终将查询作为对象返回,因此您可以使用在执行后通常可用于PDO查询的任何方法对其执行操作。
如果你知道这些是如何工作的,你可以在这里停止阅读:)我放了一些 下面列出了一些可以操作返回数据的方法 做你需要做的事。
此函数返回您请求的查询对象,因此如果您想循环查询查询的所有结果,请按以下方式使用它:
$stmt = pdoQuery("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username])->fetchAll();
foreach($stmt as $row) {
$row['name']."<br>";
}
或者,如果您只想从特定行获取单个列,则可以像这样使用它:
$username = pdoQuery("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid])->fetchColumn();
这将从username
作为字符串
uid=$uid
或者如果您想要来自1个特定行的多个值,则可以执行
$user = pdoQuery("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid])->fetch();
将返回$ user作为包含用户的用户名,名称和电子邮件的数组。
您还可以使用此函数来INSERT,UPDATE或基本上您能想到的任何类型的查询。这是你插入的方式:
pdoQuery("INSERT INTO `table_name` (`name`,`col2`, `col3`) VALUES (?,?,?)", [$name, $col1, $col2]);
自写这篇文章以来,我创建了一个名为GrumpyPDO (Hosted on Github)的新数据库包装类。
此类方法返回您请求的查询的对象,因此如果您想循环查询的所有结果,请使用它:
GrumpyPDO长语法
$stmt = $db->run("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username])->fetchAll();
GrumpyPDO短语法
$stmt = $db->all("SELECT * FROM `table_name` WHERE `user`=? ORDER BY time DESC", [$username]);
循环:
foreach($stmt as $row) {
$row['name']."<br>";
}
或者,如果您只想从特定行获取单个列,则可以像这样使用它:
//Long Syntax
$username = $db->run("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid])->fetchColumn();
//Short
$username = $db->cell("SELECT `username` FROM `users_table` WHERE uid=? ORDER BY `time` DESC", [$uid]);
这将从username
作为字符串
uid=$uid
或者如果您想要来自1个特定行的多个值,则可以执行
//Long Syntax
$user = $db->run("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid])->fetch();
//Short Syntax
$user = $db->row("SELECT `username`,`name`,`email` FROM `users_table` WHERE uid=? ORDER BY time DESC", [$uid]);
将返回$ user作为包含用户的用户名,名称和电子邮件的数组。
您还可以使用此函数来INSERT,UPDATE或基本上您能想到的任何类型的查询。这就是你插入的方式(所有DML都是相似的):
$db->run("INSERT INTO `table_name` (`name`,`col2`, `col3`) VALUES (?,?,?)", [$name, $col1, $col2]);