我现在面临的情况是,我必须从同一主机上的不同数据库创建 MySQL 视图。创建数据的团队每年使用不同的数据库(例如 sales_2014、sales_2015)等。
所有数据库都具有相同的表和几乎相同的架构。只有一些列不同,但我只需要那些相同的列,所以我不必关心那些不同的列。
对于我的项目,我需要将这些数据放在一个视图或表中。做这个的最好方式是什么?我应该为每个数据库创建一个视图,并通过不同数据库上的单个视图连接所有视图,我应该只对不同数据库中的所有表使用一个大视图,还是应该使用与视图不同的东西?
我有一个可更新的视图,指向具有部分索引的基础表。它看起来像这样
CREATE TABLE if not exists foo (
a INT,
b INT,
x INT,
y INT,
z BOOLEAN,
CONSTRAINT x_or_y CHECK (
(z and x is not null and y is null)
or
(not z and x is null and y is not null)
)
);
CREATE UNIQUE INDEX ux ON foo (x, a) WHERE z=TRUE;
CREATE UNIQUE INDEX uy ON foo (y, a) WHERE z=FALSE;
CREATE OR REPLACE VIEW foo_view AS
SELECT * FROM foo;
Run Code Online (Sandbox Code Playgroud)
也就是说,对于每一行,如果为 true,y则必须为 …
我有一个表 atbl_UserSetting,其中有一列名称为 ID,该列是具有标识和种子/增量的主键。
普通用户可以通过视图访问该表。这是视图:
CREATE OR ALTER VIEW [dbo].[atbv_UserSetting]
AS
SELECT ID, User_ID, [Key], Value
FROM dbo.atbl_UserSetting AS US
WHERE EXISTS
(SELECT TOP (1) 1 AS Expr1
FROM dbo.atbl_User AS U
WHERE (ID = US.User_ID) AND (Login = SUSER_NAME()))
Run Code Online (Sandbox Code Playgroud)
现在,当我运行此查询时,它将返回 true (1):
SELECT COLUMNPROPERTY(OBJECT_ID('atbv_UserSetting'),'ID','IsIdentity')
Run Code Online (Sandbox Code Playgroud)
INFORMATION_SCHEMA.COLUMNS 相同。
但是,如果我将视图更改为此(加入用户表):
CREATE OR ALTER VIEW [dbo].[atbv_UserSetting]
AS
SELECT US.ID, US.User_ID, US.[Key], US.Value
FROM dbo.atbl_UserSetting AS US
INNER JOIN dbo.atbl_User AS U ON U.ID = US.User_ID
WHERE U.[Login] = SUSER_NAME()
Run Code Online (Sandbox Code Playgroud)
该列的相同属性返回 false (0)。
这反过来会导致 SqlCommandBuilder …
我有一个中等大小的数据库,分布在几个表上,粗略的架构是:
每个表有大约 200,000 行。
我还有一个视图,它基本上将所有这些粘合在一起,以便我可以SELECT使用一堆 ID(通常根据会话 ID 选择它们)并在一个页面上查看所有相关数据。
该视图有效,查询计划的索引利用率似乎正常,但结果并不快:
> EXPLAIN ANALYZE SELECT(*) FROM overlay WHERE test_session=12345;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Merge Right Join (cost=7.19..74179.49 rows=10 width=305) (actual time=10680.129..10680.494 rows=4 loops=1)
Merge Cond: (p.data_id = d.id)
-> Merge Join (cost=7.19..75077.04 rows=183718 width=234) …Run Code Online (Sandbox Code Playgroud) 出于性能原因,我们正在对大量数据进行非规范化处理。基本上,通常将 JOIN 超过 10 个表的 Query 替换为没有 JOIN 的 Query,但所有必要的数据都存储/缓存在初始表中。
我是触发器的坚定拥护者,它可以帮助我保持所有数据的更新绝对透明。公司中还有其他决策者反对使用触发器(出于多种原因)并建议改为构建 VIEW,希望 VIEW 已经针对更好的数据检索进行了优化。
在 MySQL 中是这种情况吗?
我的数据库中有一些无效的视图和函数。
我不确定是什么更改导致这些对象无效,因为很多人都在使用同一个数据库。
如何查看导致视图无效的更改?
我有一个包含 varchar 类型字段中的 XML 数据的表。该字段用于存储来自各种不同 XML 模式的数据,其中一些通过存储在另一个表中的记录相关联。
我最近创建了一些解析 XML 的视图,并且在某些情况下创建了一些值的枢轴。这些视图为我的报告提供了极好的数据,但对性能造成了严重影响。我想知道是否可以通过索引提高性能。
下面是一个视图的例子:
create view StudentHours as
select
x.TableRecordId as Id
, x.RecordXml.value('(/TableRecord/LOGDate)[1]', 'DateTime') as LogDate
, x.RecordXml.value('(/TableRecord/LOGHours)[1]', 'float') as Hours
, x.RecordXml.value('(/TableRecord/LOGApproved)[1]', 'varchar(10)') as Approved
, y.PKTableRecordId as CourseId
from
(select TableRecordId, Cast([Schema] as Xml) as RecordXml
from TableRecords where TableSchemaId = 1857) as x
join TableRecordRelations as y on x.TableRecordId = y.FKTableRecordId
Run Code Online (Sandbox Code Playgroud)
然后,我将在其他执行聚合等操作的视图中使用此视图。
名为 TableRecords 的表在其唯一 id TableRecordId 上有一个索引,TableRecordRelations 在其重要字段上也有索引。
添加一两个索引是否有助于此视图的性能?是否需要更多数据来确定这一点?
我没有使用 MySQL 的经验。我的老板optimize针对 MySQL 数据库运行了一个。反对一堆观点,我们得到了消息
“tablexyz”不是基表
下一条消息是
腐败
它似乎只针对视图,我们没有收到针对基表的任何这些错误消息。
这看起来像是不正确的错误消息,还是我们的表有问题?
有人错误地在数据库表中创建了一堆 nchar 字段。我注意到了这一点,在检查了这个问题之后,我们将这些字段移动到 nvarchar 类型并修剪里面的值。
在我的脚本中,我目前仅限于拉取具有 nchar 类型的表,假设由表提供的视图知道更新它们的值。这个假设是否正确,或者我也应该在这个列表中包含视图?
作为参考,当前形式的脚本如下(主要取自这个伟大的 SO 答案):
declare @tn nvarchar(128)
declare @cn nvarchar(128)
declare @ln int
declare @sql as nvarchar(1000)
declare c cursor for
select cols.table_name,cols.column_name,cols.character_maximum_length
from information_schema.columns cols
inner join information_schema.tables tabs
on (cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA and cols.TABLE_NAME = tabs.TABLE_NAME)
where cols.data_type ='nchar' and tabs.TABLE_TYPE = 'BASE TABLE'
open c
fetch next from c into @tn, @cn, @ln
while @@FETCH_STATUS = 0
begin
set @sql = 'alter table ' + @tn + …Run Code Online (Sandbox Code Playgroud) view ×10
mysql ×3
sql-server ×3
oracle ×2
postgresql ×2
corruption ×1
datatypes ×1
index ×1
join ×1
performance ×1
terminology ×1
trigger ×1
upsert ×1