我的公司让我为Oracle ORM完成Oracle的后端工作。令我惊讶的是,即使对于简单的东西,RDBMS也会有多么不同。我已经学到了很多关于Oracle和其他RDBMS之间差异的知识。出于纯粹的好奇心,我想了解更多。
在将SQL从一个平台移植到另一个平台方面有哪些常见的“问题”?
请,每个答案只有一个问题。
答案 0 :(得分:4)
Oracle似乎没有游标问题,它们在SQL服务器中是一个巨大的性能问题。
实际上,几乎所有的性能调优都是特定于数据库的(这就是为什么ANSII标准代码与设计成特定于数据库的SQL的特定风格的更好方法相比通常表现得非常差)。
日期是另一件似乎从数据库到数据库处理不同的事情。
数据类型也不相同。倾向于让SQL Server新手的一件事是时间戳数据类型与日期和时间完全无关,并且无法转换为数据时间值。
答案 1 :(得分:2)
另一个例子是生成唯一(通常是代理)主键。
许多数据库(例如SQL Server和sqlite)都允许将列声明为标识:通常,如果插入时缺少此列的值,则数据库将为该列生成唯一值。
相比之下,Oracle会让您创建一个与表分开的序列,然后在序列上使用nextval来生成下一个值:CREATE SEQUENCE test_seq;
SELECT test_seq.nextval FROM dual;
或者,更典型的是:
INSERT INTO foo(id, title) VALUES (test_seq.nextval, 'bar');
答案 2 :(得分:2)
在将SQL从一个平台移植到另一个平台方面有哪些常见的“问题”?
尝试通过将词典单词替换为短语,尝试从English
转换为Russian
。
适用于你好和再见,但玛丽有一只小羊羔没有说莎士比亚。
不同的RDBMS
具有不同的文化,尽管名称中有SQL
。
例如,行限制。
在Oracle
:
WHERE rownum = 1
在SQL Server
:
SELECT TOP 1
在MySQL
和PostgreSQL
:
LIMIT 1
在DB2
:
SELECT * ... FETCH FIRST 1 ROW ONLY
四个不同的子句。
答案 3 :(得分:2)
多值IN子句查询。我曾经一直在Oracle上使用这些,并且惊讶地发现你无法在SQL Server中执行此操作。例如,此查询:
SELECT * FROM mytable WHERE (col1, col2) IN ( SELECT col1, col2 FROM othertable )
答案 4 :(得分:2)
Oracle不允许您插入空字符串:它们会以静默方式转换为NULL。
答案 5 :(得分:2)
Oracle不允许没有FROM子句的select语句。因此,您无法执行以下查询:
SELECT 1
相反,您必须说该查询来自DUAL
表:
SELECT 1 FROM DUAL
答案 6 :(得分:2)
Oracle采用与MySQL相反的引用方法。
MySQL: `object_name`, 'string', "string"
Oracle: "object_name", 'string'
此外,逃避是不同的。
MySQL: 'It\'s easy'
Oracle: 'It''s slightly confusing'
(注意,为了转义Oracle中除引号以外的任何内容,您可以在查询中使用ESCAPE指令; SELECT * FROM testTable WHERE percent = '50 \%'ESCAPE'\')
答案 7 :(得分:2)
我拥有的SQL Server和Oracle之间的差异列表 移植时遇到:
Think ANSI Standard SQL Is Fully Portable Between Databases? Think Again.
答案 8 :(得分:1)
我记得一个特殊的Oracle问题,让我彻底摆脱了猜测。我不确定这是实例的配置还是默认设置,但我们在IN语句中不能有超过1000个元素。所以我们不得不欺骗它去做想要的事情:
SELECT Col1,Col2
FROM Table
WHERE Code IN (1,2,3,...,1000)
OR Code IN (1001,1002,1003,...,2000)
等。
丑陋,但它奏效了。
(在任何人指出子查询或内联视图的明显解决方案之前,查询是在完全不同的系统上生成的)
答案 9 :(得分:1)
性能问题很重要。例如,Oracle中的视图是AFAIK,与表格一样快。当我不得不使用SQLServer时,情况并非如此。这些视图有效地扼杀了性能,使相同的选择减慢了一个数量级或更多(直接从表中查询,比如说0.5秒,而使用视图可能需要一分钟)。它们的使用也有很多限制,例如并非所有SQL函数都可用于视图。
请注意,六年前这是真的5-6,我不知道微软是否已经改进了这一点。
答案 10 :(得分:1)
隐藏连接语法,就像外部联接的Oracle(+)语法一样。在一个我曾经工作过这种语法的公司,而不是标准的LEFT OUTER JOIN / LEFT JOIN语法,这使得将一些东西移植到MySQL上非常痛苦。
答案 11 :(得分:1)
Oracle不允许您在一个查询中有多个插入。 MySQL允许这样:
INSERT INTO test(id, name) VALUES (1, 'foo'),(2, 'bar');
答案 12 :(得分:1)
对于产品特定问题的全局,您需要了解逻辑数据库设计和物理数据库设计之间的区别。
逻辑数据库设计主要与表的功能有关。表的特征包括列和约束。虽然表本身是物理的,但表设计通常从一个数据库系统到另一个数据库系统非常便携。某些数据类型的工作方式有所不同,语法上有一些差异,例如是否可以在表名中使用下划线。但是一个好的逻辑设计应该从一个系统移植到另一个系统,只需要很小的改动或没有改变。
物理数据库设计主要与表结构所依赖的基础结构的功能有关。几乎所有系统都支持索引,默认索引类型是B-tree,尽管它可能被称为其他东西。但从那时起,每个系统都有自己的物理特性,从一个系统到另一个系统可能完全不同。 Oracle的典型物理特性是表空间。与表空间紧密相关的是表和表空间之间的映射。物理设计必须在特定系统的基础上完成。
除了您正在使用的RDM系统之外,您还需要在设计中考虑数据量,负载,响应时间要求以及磁盘等系统资源。好消息是,可以在不更改应用程序代码的情况下对物理设计进行大量更改。这称为物理数据独立性。这意味着在您编写了一些应用程序代码并加载了一些数据之后,您可以稍微调整和调整物理设计。
您可能希望查看一些有关数据库设计的书籍,以深入了解逻辑和物理设计以及它们之间的区别。一些受欢迎的作者是C.J.Date和Joe Celko。
答案 13 :(得分:1)
临时表 - Oracle vs SQL Server / MySQL。从Oracle过渡到MS / MySQL,没问题。反过来说,有点不同。
答案 14 :(得分:0)
设置操作员支持。
除了UNION / UNION ALL之外,设置运营商支持在数据库中非常不稳定。 Oracle和SQL服务器支持其中的大多数,但Oracle支持MINUS操作以及等效的标准EXCEPT DISTINCT操作。 AFIK,MySQL只支持UNION(没有INTERSECT或EXCEPT支持)。
答案 15 :(得分:0)
我不确定在Python附带的驱动程序中是否存在这种情况,但在我使用的“Horrable”版本中,如果结果集中的列为列中的所有值返回NULL,则 column本身不会在结果集的结构中返回。这可能(并且经常会)导致生产中的错误,这些错误在开发过程中无法复制。
由于你正在离开Oracle,这应该不是一个问题,但是有一个关键字开发人员用来缓解这个“功能”,我怀疑MySQL支持这个功能。但我忘了它是什么,谷歌没有帮助。
答案 16 :(得分:0)
不同的数据库处理二进制数据有点不同。例如,这将在MySQL下运行:
mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t SET c = 'z';
Query OK, 1 row affected (0.01 sec)
但是,Oracle依赖于这些值为十六进制:
SQL> CREATE TABLE t (c RAW(3));
Table created.
SQL> INSERT INTO t VALUES ('z');
INSERT INTO t VALUES ('z')
*
ERROR at line 1:
ORA-01465: invalid hex number
相反,我们必须将其转换为十六进制:
SQL> INSERT INTO t VALUES (rawtohex('z'));
1 row created.