【问题标题】:Can MySQL check that file exists?MySQL可以检查该文件是否存在?
【发布时间】:2013-06-16 01:57:06
【问题描述】:

我有一个表,其中包含 HDD 上真实文件的相对路径。例如:

SELECT * FROM images -->
id | path
1  | /files/1.jpg
2  | /files/2.jpg

我可以创建一个查询来选择所有指向不存在文件的记录吗?我需要通过 MySql 服务器准确地检查它,而不是在 PHP 客户端中使用迭代。

【问题讨论】:

  • 这是一个非常糟糕的设计。
  • 我不相信 MySQL 对这类事情有任何形式的文件系统访问权限。您需要使用外部语言来实现这一点。
  • Bogdan Burim,为什么不好?最好将图像数据放在 BINARY 字段中还是什么?
  • 看看stackoverflow.com/questions/8931696/… 是否可以成为你想要达到的目标的建议

标签: mysql file-exists


【解决方案1】:

MySQLLOAD_FILE 命令对可以打开的文件有非常严格的要求。来自 MySQL 文档:

[LOAD_FILE] 读取文件并将文件内容作为字符串返回。要使用此功能,文件必须位于服务器主机上,您必须指定文件的完整路径名,并且您必须具有 FILE 权限。该文件必须可供所有人读取,并且其大小小于 max_allowed_pa​​cket 字节。如果将secure_file_priv系统变量设置为非空目录名,则要加载的文件必须位于该目录中。

因此,如果mysql 用户无法访问该文件或不满足任何其他要求,LOAD_FILE 将返回Null


您可以使用awk 获取与丢失文件对应的 ID 列表:

mysql db_name --batch -s -e "SELECT id, path FROM images" \ | awk '{if(system("[ -e " $2 " ]") == 1) {print $1}}' \ >> 缺少_ids.txt

或者干脆使用bash:

mysql db_name --batch -s -e "SELECT id, path FROM images" \ |同时读取 id 路径;如果 [[ -e "$path" ]] ;然后回显 $id ;完毕 >> 缺少_ids.txt

这还具有比LOAD_FILE快得多的优势。

【讨论】:

  • 如果文件名包含圆括号“ ( ) ”,则此命令会引发错误。有没有办法解决这个问题,所以它可以处理任何类型的文件名?
  • @CarstenSchmitz 我添加了一个使用 bash while 循环的示例。您可以尝试使用它。
【解决方案2】:

我会使用这样的查询:

SELECT id, path, ISNULL(LOAD_FILE(path)) as not_exists
FROM images
HAVING not_exists = 1

函数LOAD_FILE尝试将文件加载为字符串,失败时返回NULL

请注意,这种情况下的失败可能是由于 mysql 根本无法读取该特定位置,即使该文件确实存在。

编辑:

正如@ostrokach 在 cmets 中指出的那样,这不是标准 SQL,即使 MySQL 允许它遵循它可能的标准:

SELECT *
FROM images
WHERE LOAD_FILE(PATH) IS NULL

【讨论】:

  • 我无法为自己工作。返回的所有文件实际上都存在。什么可能意味着这个本地位置对 MySQL 来说是不可读的? stackoverflow.com/questions/27495830/…
  • 可能是运行 MySQL 守护程序的用户无法访问包含这些文件的文件夹。
  • HAVING not_exists = 1 部分是错误的,因为您没有按 not_exists 分组。如果您只想选择那些存在文件的行,您应该执行以下操作:SELECT id, path FROM images WHERE LOAD_FILE(path) is NULL;
  • 是的,它不是标准 SQL,但 MySQL 允许。但我喜欢你的建议,我会编辑我的答案:)
  • 这似乎很浪费。 LOAD_FILE 函数将读取每个确实存在的文件的内容。这使得该查询无用地使用大量 I/O。仅仅因为某人可以做某事并不意味着这是一个好主意。这个任务写成脚本会好得多!
【解决方案3】:

使用库存 MySQL 是不可能的。但是,您可以编写 UDF(用户定义函数),可能是在 C 中,使用 CREATE FUNCTION 语句加载它,然后像使用任何内置函数一样从 MySQL 中使用它。

【讨论】:

  • 据我所知,mysql自定义创建的函数只使用SQL。
  • @MatteoTassinari 请阅读链接资源。您可以创建用 SQL 编写的“存储函数”,也可以创建编译成共享库并在运行时加载的“用户定义函数”。
  • 看来我错了,抱歉,谢谢指出:)
【解决方案4】:

MYSQL 只处理数据库,因此如果文件存在,您无法触发 SQL 语句来检查 HDD。您需要遍历行并使用 PHP 进行检查。

【讨论】:

  • 谢谢。我想可能是如果 mysql 有 LOAD DATA INFILE 等功能,换句话说可以访问用户文件,那么它可以检查文件是否存在。
  • 或者您可以将文件作为二进制大对象 BLOB 存储在数据库中,并检查它们是否存在于数据库中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2017-02-16
  • 2016-02-29
  • 2021-12-25
相关资源
最近更新 更多