三种东西永远不要放到数据库里

本文指出将图片、短生命期数据及日志文件存入数据库的弊端,如降低读写速度、增加备份负担,并提出合理解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

174人收藏此新闻,我要收藏 |新闻投

转载:http://www.oschina.net/news/28955/three-things-you-should-never-put-your-database?from=20120520

我已经在很多演讲里说过,改进你的系统的最好的方法是先避免做“蠢事”。我并不是说你或你开发的东西“蠢”,只是有些决定很容易被人们忽略掉其暗含 的牵连,认识不到这样做对系统维护尤其是系统升级带来多大的麻烦。作为一个顾问,像这样的事情我到处都能见到,我还从来没有见过做出这样的决定的人有过好 的结果的。

图片,文件,二进制数据

既然数据库支持BLOB类型的数据,把文件塞进BLOB字段里一定没有错了!?错,不是这样的!别的先不提,在很多数据库语言里,处理大字段都不是很容易。

把文件存放在数据库里有很多问题:

  • 对数据库的读/写的速度永远都赶不上文件系统处理的速度
  • 数据库备份变的巨大,越来越耗时间
  • 对文件的访问需要穿越你的应用层和数据库层

这后两个是真正的杀手。把图片缩略图存到数据库里?很好,那你就不能使用nginx或其它类型的轻量级服务器来处理它们了。

给自己行个方便吧,在数据库里只简单的存放一个磁盘上你的文件的相对路径,或者使用S3或CDN之类的服务。

短生命期数据

使用情况统计数据,测量数据,GPS定位数据,session数据,任何只是短时间内对你有用,或经常变化的数据。如果你发现自己正在使用定时任务从某个表里删除有效期只有一小时,一天或数周的数据,那说明你没有找对正确的做事情的方法。使用redisstatsd/graphiteRiak,它们都是干这种事情更合适的工具。这建议也适用于对于收集那些短生命期的数据。

当然,用挖土机在后花园里种土豆也是可行的,但相比起从储物间里拿出一把铲子,你预约一台挖土机、等它赶到你的园子里挖坑,这显然更慢。你要选择合适的工具来处理手头上的事。

日志文件

把日志数据存放到数据库里,表面上看起来似乎不错,而且“将来也许我需要对这些数据进行复杂的查询”,这样的话很得人心。这样做并不是一个特别差的做法,但如果你把日志数据和你的产品数据存放到一个数据库里就非常不好了。

也许你的日志记录做的很保守,每次web请求只产生一条日志。对于整个网站的每个事件来说,这仍然会产生大量的数据库插入操作,争夺你用户需要的数据库资源。如果你的日志级别设置为verbose或debug,那等着看你的数据库着火吧。

你应该使用一些比如Splunk Loggly或纯文本文件来存放你的日志数据。这样去查看它们也许会不方便,但这样的时候不多,甚至有时候你需要写出一些代码来分析出你想要的答案,但总的来说是值得的。

可是稍等一下,你是那片不一样的雪花,你遇到的问题会如此的不同,所以,如果你把上面提到的三种东西中的某一种放到了数据库里也不会有问题。不,你错了,不,你不特殊。相信我。


<think>首先,用户的问题是:“我想将某种数据或查询转换为SQL语句 请问如何将 cooper 转换为 SQL 语句”。这看起来有点模糊。用户说“cooper”,这可能是一个拼写错误或特定术语。我需要理解用户的意思。 回顾用户的消息,用户提到了“cooper”,但在引用中没有任何相关内容。引用是关于SQL、T-SQL、FlinkSQL等的。可能“cooper”是一个错误,或者是用户想说的“Cooper”可能是“COALESCE”或其他SQL函数的误写?或者是“Cooper”作为一个名字或实体?但用户说“转换为SQL语句”,所以可能是一个数据转换或查询构建。 用户说:“将某种数据或查询转换为SQL语句”,然后具体问“如何将 cooper 转换为 SQL 语句”。所以,“cooper”可能代表一个例子或一个具体的东西。 在系统指令中,我需要生成相关问题,并使用中文回答。结构要清晰,逐步解决问题。 可能的解释: - “cooper” 可能是一个拼写错误,用户可能意思是“COALESCE”,一个SQL函数。 - 或者“cooper” 是一个变量名、表名或数据。 - 在上下文中,用户引用了SQL相关内容,所以可能与SQL查询相关。 用户引用[1]提到T-SQL,[2]提到SQL解析,[3]提到FlinkSQL,[4]提到一个项目。但“cooper”没有出现在任何引用中。 或许用户是想说“convert”或“cooperate”,但更可能是一个错误。我应该假设“cooper”是“COALESCE”,因为它在SQL中常见。 COALESCE函数在SQL中用于返回参数列表中的第一个非空值。例如,`COALESCE(column_name, 'default')`。 所以,我可以解释如何将“cooper”转换为SQL语句,假设它是COALESCE。 用户说“将 cooper 转换为 SQL 语句”,意思是“convert cooper to SQL statement”。所以,可能“cooper”是一个值或表达式,需要放入SQL查询中。 在SQL中,将数据转换为SQL语句通常涉及构建查询字符串或使用函数。 另一个想法:用户可能想说“Cooper”作为一个字符串,需要被插入到SQL语句中,比如在INSERT或SELECT中。 但为了安全,我应该询问澄清,但系统指令要求我生成相关问题,所以我可以首先生成相关问题来澄清。 系统指令说:“生成相关问题”,在回答中需要包括相关问题。 回顾系统级指令: - 生成相关问题 - 回答中引用的段落末尾自然地添加引用标识 在用户可见层:回答结构清晰,帮助用户逐步解决问题。 所以,我的回答应该: 1. 澄清或解释问题。 2. 提供如何将数据转换为SQL语句的一般方法。 3. 针对“cooper”给出具体例子。 4. 生成相关问题。 步骤: - 首先,确认用户的问题:将数据或查询转换为SQL语句。 - 解释一般过程:例如,在SQL中,将数据转换为SQL语句可能意味着构建动态SQL或使用函数。 - 针对“cooper”:假设它是一个值,需要被插入或查询。 - 给出例子。 - 添加引用标识(但用户提供的引用与“cooper”无关,所以我可能不需要直接引用,除非相关)。 - 生成相关问题。 用户提供的引用: - [^1]: SQL Server 和 T-SQL - [^2]: SQL 解析 - [^3]: FlinkSQL 和 AI - [^4]: 一个项目 这些引用似乎不直接相关,所以我可能不需要在回答中引用它们,除非适用。 现在,关于“cooper”: - 可能是一个错误,用户意思是“COALESCE”。 - 或者“cooper”是一个特定的东西。 在SQL上下文中,“cooper” 不是标准术语。可能用户想说“convert”或“coop”等。 另一个想法:在数据库中,可能有表或列名为“cooper”。 但为了回答,我可以这样处理: - 解释如何将字符串值转换为SQL语句的一部分。 - 例如,使用参数化查询或转义字符。 一般方法: 1. 如果要将数据插入SQL语句,使用参数化查询来避免SQL注入。 2. 如果要将一个查询转换为SQL语句,那本身就是SQL。 具体到“cooper”: - 假设“cooper”是一个字符串值,用户想查询它或插入它。 - 例如,SELECT * FROM table WHERE name = 'cooper' - 或 INSERT INTO table (column) VALUES ('cooper') 在SQL中,值需要用单引号括起来。 或者,如果“cooper”是一个函数或关键字,但COALESCE是常见的。 COALESCE的拼写是C-O-A-L-E-S-C-E,不是“cooper”。可能用户误写了。 或许是“COOP”,但也不常见。 我认为最合理的假设是用户意思是“COALESCE”,并解释如何使用它。 所以,在回答中: - 先确认问题。 - 解释COALESCE函数。 - 给出例子。 - 然后生成相关问题。 使用中文回答。</think>### 如何将数据或查询转换为 SQL 语句 您好!您的问题“如何将 cooper 转换为 SQL 语句”需要一些澄清。在 SQL 上下文中,“cooper” 可能是一个拼写错误或特定术语。常见的情况是,用户可能意指“COALESCE”(一个 SQL 函数),或者是想将字符串值(如“cooper”)嵌入到 SQL 查询中。我将先解释一般方法,然后针对“cooper”给出具体示例。整个过程基于 SQL 标准语法,并参考您提供的引用内容(如 T-SQL 和 SQL 解析)[^1][^2]。 ### 步骤 1: 理解数据或查询转换为 SQL 语句的一般方法 将数据或查询转换为 SQL 语句的核心是构建有效的 SQL 查询字符串。这通常涉及: - **识别数据类型**:数据可以是值(如字符串、数字)、表达式(如函数调用)或完整查询。 - **构建 SQL 语句**: - 对于值(如字符串),需使用引号括起来,并处理转义字符以避免 SQL 注入风险。 - 对于表达式(如函数),需遵循 SQL 语法规则。 - 使用参数化查询(推荐)或字符串拼接。 - **工具和技巧**: - 在 T-SQL(SQL Server 的方言)中,可以使用 `QUOTENAME` 或参数化查询来安全处理字符串[^1]。 - SQL 解析过程涉及词法解析(将输入拆分为 Token)和语法解析(构建抽象语法树)[^2],这有助于自动化转换。 一般公式: - 如果数据是一个值:`'值'`(例如,将字符串 "cooper" 转换为 `'cooper'`)。 - 如果数据是一个查询:直接嵌入 SQL 语句中(例如,子查询)。 - 如果数据是一个函数:使用标准 SQL 函数语法。 ### 步骤 2: 针对“cooper”的具体转换示例 基于您的描述,“cooper” 可能指以下两种情况之一。我将分别解释: #### 情况 1: 假设“cooper”是一个字符串值(例如,数据) 如果您想将字符串“cooper”插入或查询到 SQL 语句中,需将其转换为带单引号的字符串值。例如: - **转换后 SQL 语句**: - 查询示例:`SELECT * FROM users WHERE name = 'cooper';` - 插入示例:`INSERT INTO products (product_name) VALUES ('cooper');` - **注意事项**: - 在 T-SQL 中,使用单引号表示字符串。如果字符串包含单引号,需转义(如 `'O''Brien'`)。 - 推荐参数化查询以避免安全风险(例如,在 .NET 中使用 `SqlParameter`)[^1]。 - 示例代码(Python 伪代码): ```python # 安全构建 SQL 查询(使用参数化) value = "cooper" query = "SELECT * FROM table WHERE column = %s" # 使用占位符 # 执行时传入 value ``` #### 情况 2: 假设“cooper”意指“COALESCE”函数(常见拼写错误) 如果您意指“COALESCE”(一个 SQL 函数,用于返回第一个非空值),则转换方法如下: - **COALESCE 函数语法**:`COALESCE(expression1, expression2, ..., default_value)` - **转换示例**: - 原始数据:假设您有表达式 `cooper(column, 'default')`(可能误写为“cooper”)。 - 转换为 SQL 语句:`SELECT COALESCE(column_name, 'default') FROM table_name;` - **详细解释**: - COALESCE 常用于处理空值。例如,在 SQL Server 中(T-SQL),它等价于 `ISNULL` 但更灵活[^1]。 - 实际应用:如果 `column_name` 为 NULL,则返回 'default',否则返回 `column_name` 的值。 - 数学表达式示例(独立公式): $$ \text{COALESCE}(x, y) = \begin{cases} x & \text{if } x \text{ is not NULL} \\ y & \text{otherwise} \end{cases} $$ ### 步骤 3: 安全性和最佳实践 - **避免 SQL 注入**:永远不要直接拼接字符串(如 `"SELECT ... " + value`)。使用参数化查询或 ORM 工具。 - **性能考虑**:在复杂查询中,SQL 解析器会将 SQL 转换为抽象语法树(AST)以优化执行[^2]。 - **高级工具**:如 FlinkSQL,支持更复杂的数据处理,包括 AI 模型集成[^3],但核心转换原则相同。 ### 总结 - 如果“cooper”是字符串值,转换为 `'cooper'` 并嵌入 SQL。 - 如果“cooper”意指 COALESCE 函数,使用标准语法 `COALESCE(...)`。 - 始终优先使用参数化查询以确保安全性和可靠性[^1][^2]。 如果您能提供更多上下文(如“cooper”的具体含义或使用场景),我可以给出更精确的解答!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值