SQL Server的Replication中的Article必須要有Primary Key

這個是朋友請我查的資料, 其實邏輯上還蠻容易的, 因為 SQL Server的Transactional Replication是參考table的primary key來進行新增刪除修改的, 若是該table沒有primary key的話, 是沒有辦法加入到publication的article裡的.

資料可以參考這裡:

http://msdn.microsoft.com/en-US/library/ms152559%28v=SQL.90%29.aspx

其中的:

Limitations on Publishing Objects

  • The maximum number of articles and columns that can be published differs by publication type. For more information, see the “Replication Objects” section of Maximum Capacity Specifications for SQL Server 2005.
  • Stored procedures, views, triggers, and user-defined functions that are defined as WITH ENCRYPTION cannot be published as part of SQL Server replication.
  • XML schema collections can be replicated but changes are not replicated after the initial snapshot.
  • Tables published for transactional replication must have a primary key. If a table is in a transactional replication publication, you cannot disable any indexes that are associated with primary key columns. These indexes are required by replication. To disable an index, you must first drop the table from the publication.
  • Bound defaults created with sp_bindefault (Transact-SQL) are not replicated (bound defaults are deprecated in favor of defaults created with the DEFAULT keyword of ALTER TABLE or CREATE TABLE).

 

上面紅字部分就是說明這個限制.

 

更新到wordpress 3.1

2/24 wordpress 釋出了更新版本到 3.1 了.

果然這從上次更新到這次更新都還沒有發表新文章, 說中了更新的速度比寫文章的速度還要快的這件事.

3.1 版本新的功能介紹在這裡:

http://codex.wordpress.org/Version_3.1

其中比較明顯的是blog版主登入的狀況下, 上面會出現一個 admin bar, 方便版主選寫文章或是管理文章及回覆使用, 還蠻貼心的設計.

 

SQL Server Optimization

這篇文章寫得十分有用, 建議有在做資料庫效能調校的朋友們可以讀一下.

http://msdn.microsoft.com/en-us/library/aa964133%28SQL.90%29.aspx

其中最後有還蠻精要的整理, 也就是這段落: Optimization Rules of Thumb

對於 index 等的設計都有蠻好的解說及經驗, 利用執行計劃 (execution plan) 的數據資料來檢視索引建立的狀況是否良好, 而且也應該適時更新統計資料(statistics), 利用這個指令: update statistics <TableName>, 更新好統計資料的 table , 再來檢視執行計劃, 會更準確.

另外查詢時, 儘量不要對資料欄位進行操作, 也就是以原本的資料來做比對及判斷, 查詢引擎才會使用對應的索引, 若利用了函數或一些轉型, 讓原始欄位改變的查詢條件, 查詢引擎就沒有辦法使用索引帶來的好處了, 如文章中舉的例子, 像是:

cast(DateField as varchar(20)) = @dateString

應該調整為 @dateString 轉型成為 DateField 的型態, 再來進行查詢, 肯定效果會更好, 另外還有這個例子(不是文章中提到的)也是很經典, 像是

Left(VarCharField, 1) = ‘k’

應該要改為

VarCharField like ‘k%’

這樣也是較函數來得佳, 都是可以改善查詢效能的.

試看看, 應該都有空間可以再精進!

原來在3.0時mu的版本就已和主版本合併了

剛在逛 mu.wordpress.org 網站時, 才發現, 原來已經合併到主版本上了, 而且是稱之為 multi-site 的 wordpress, 也就是說, wordpress 本身已經 support 多人使用囉. 中文的網站有詳細的說明在此: http://tw.wordpress.org/2010/06/18/wordpress-3-0-thelonious/ , 其實這樣子的話, 相信會更方便維護及更新了.

wordpress 一直是我覺得發展的很好的一個開源 blog 系統, 即使是 mu的版本, 大多數的單人版佈景主題, 插件, 都能夠幾乎無痛地在 mu 多人版使用, 架構上十分良好, 合併起來, 相信是更棒的開發方式.

把 mu 的最後記錄畫面抓下來記念一下:

升級至3.0.1

今天進行wordpress 的版本升級, 把系統由原來的 2.9.1.1更新到 3.0.1

這次的升級有個多媒體rewrite 檔要手動更新, 其中是將原來的 .htaccess 中的 rewrite 由原本的 wp-content/blogs.php 改為 wp-includes/ms-files.php 而原來的 blogs.php 已無作用了, 可以進行移除.

另外也從 http://tw.wordpress.org 下載了最新的語系檔來更新, 完成這次的升級!

SQL Server 中的 Pivot 語法

從 SQL Server 2005 起, 支援了 Pivot 語法及 UnPivot 語法.

利用 Pivot 語法, 可以做出一些轉置及特殊報表使用的查詢結果(對於要分析資料時特別有用).

先來建立範例資料, 這個資料表是一個流水號(logid, 一個會員編號 userno, 一個投票標的號 voteid, 一個時間欄位 createtime), 為能將資料表模擬真實的狀況, 建立一些資料來供應用, script 如下:


CREATE TABLE VOTELOG (logid int identity(1,1), userno int, voteid int, createtime datetime default getdate())
insert into VOTELOG (userno, voteid, createtime) values (1, 1, '2010/7/1 1:15')
insert into VOTELOG (userno, voteid, createtime) values (2, 1, '2010/7/1 3:27')
insert into VOTELOG (userno, voteid, createtime) values (4, 2, '2010/7/1 3:29')
insert into VOTELOG (userno, voteid, createtime) values (15, 2, '2010/7/1 16:31')
insert into VOTELOG (userno, voteid, createtime) values (35, 1, '2010/7/1 17:31')
insert into VOTELOG (userno, voteid, createtime) values (24, 1, '2010/7/1 17:38')
insert into VOTELOG (userno, voteid, createtime) values (8, 2, '2010/7/1 20:18')
insert into VOTELOG (userno, voteid, createtime) values (7, 2, '2010/7/2 2:22')
insert into VOTELOG (userno, voteid, createtime) values (32, 1, '2010/7/2 2:36')
insert into VOTELOG (userno, voteid, createtime) values (9, 1, '2010/7/2 10:09')
insert into VOTELOG (userno, voteid, createtime) values (25, 2, '2010/7/2 13:35')
insert into VOTELOG (userno, voteid, createtime) values (19, 2, '2010/7/2 18:19')
insert into VOTELOG (userno, voteid, createtime) values (16, 2, '2010/7/2 19:28')
insert into VOTELOG (userno, voteid, createtime) values (6, 1, '2010/7/2 23:06')
insert into VOTELOG (userno, voteid, createtime) values (36, 2, '2010/7/3 0:42')
insert into VOTELOG (userno, voteid, createtime) values (18, 2, '2010/7/3 2:19')

假如現在我們需要分時的每日投票狀況的報表, 可以使用如下的 pivot查詢:


select dates, [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23]
from (select convert(varchar, createtime, 111) as dates, datepart(hh, createtime) as hours from votelog ) as cum
pivot (count(hours) for hours in ( [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23] )) as pv

查詢結果如下:

這樣可以很清楚地呈現出, 每日分時的統計狀況, 當然, 若是要查的是分開兩個候選人的結果, 僅需要在中間的子查詢(cum)的裡面多加入 where 條件即可.

另外多提一個部分, 這樣的查詢, 可以在子查詢先做集總, 再進行 pivot, 效果會更好(尤其在資料量愈大時), 語法如下:


select dates, [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23]
from (select convert(varchar, createtime, 111) as dates, datepart(hh, createtime) as hours, count(*) as counts from votelog group by convert(varchar, createtime, 111), datepart(hh, createtime) ) as cum
pivot (count(counts) for hours in ( [0],[1],[2],[3],[4],[5],[6],[7], [8],[9],[10],[11],[12],[13],[14],[15], [16],[17],[18],[19],[20],[21],[22],[23] )) as pv

也就是在子查詢中(cum), 先 group 好, 再進行 pivot 的查詢(但記得要用sum前面count結果), 這樣的效果會更有效率.

pivot 及 unpivot 語法可以參考以下資料:

使用 PIVOT 和 UNPIVOT: http://technet.microsoft.com/zh-tw/library/ms177410%28SQL.90%29.aspx

另外有人整理好的 cross-table stored procedure也很方便, 可以參考這篇: http://www.sqlteam.com/article/dynamic-cross-tabs-pivot-tables

主動發佈給搜尋引擎的wordpress plugin PuSHPress

從高登那裡看來看: http://gordon168.tw/?p=368

很有意思的 plugin, 可以主動發行內容到 google 搜尋引擎, 比從搜尋引擎來抓的速度會快很多. 達成發行文章後, 馬上發佈到各 subscriber 及搜尋引擎資料庫.

這個 PubSubHubBub 很有趣的地方在於是 google 支持的一項新 protocol, 用來把內容發佈出來的資料, 主動對 hub 發行, 並主動通知 subscriber, 可以達到更有效的發行.

不過這種東西的下場, 很有可能被濫用或一些廣告, 所以…..

不過也不用想太多, 基本上就是用就對了.

PubSubHubBub 的專案連結: http://code.google.com/p/pubsubhubbub/

plugin連結: http://wordpress.org/extend/plugins/pushpress/

這裡有個介紹 What is PubSubHubbub? 的影片, 可以參考: http://www.youtube.com/watch?v=B5kHx0rGkec

SQL Server中的索引離散狀況

SQL Server 資料庫中的索引是用來加速查詢效率的一種方式, 利用了空間換取時間的方法來將查詢的速度增加.

既然是利用空間換取時間的方法, 代表著該存放的空間, 資料的排列狀況就會隨著時間的過去, 有資料的新增, 刪除, 修改時, 造成的索引離散狀況, 若是索引離散時, 代表著存取這些索引的 IO 量會增加, 也代表著效率會下降的狀況會發生.

如何查詢這個資料, 可以參考這篇文章: http://sharedderrick.blogspot.com/2010/02/index-fragmentation.html 有詳細的說明, 利用該查詢指令, 若是要查找特定 table 的話, 可以這樣下(SQL Server 2005以上版本):

SELECT sch.name N’結構描述’, obj.name N’資料表’,
inx.name AS N’索引名稱’,
index_type_desc N’索引類型’,
avg_fragmentation_in_percent ‘片段(%)’,
avg_page_space_used_in_percent N’頁面飽和度(%)’,
fragment_count,
avg_fragment_size_in_pages,
page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), OBJECT_ID(‘TABLE_NAME’),NULL, NULL, ‘SAMPLED’) AS phy
INNER JOIN sys.indexes AS inx ON phy.object_id = inx.object_id AND phy.index_id = inx.index_id
INNER JOIN sys.objects AS obj ON phy.object_id = obj.object_id
INNER JOIN sys.schemas AS sch ON obj.schema_id = sch.schema_id
WHERE index_type_desc <> ‘HEAP’  AND fragment_count IS NOT NULL AND avg_fragment_size_in_pages IS NOT NULL
ORDER BY 5 DESC

利用了 OBJECT_ID() 函數, 把 table 的 object id 找出來, 便能指定查找特定 table 中的索引離散狀況.

根據微軟官方的資料: http://technet.microsoft.com/zh-tw/library/ms189858.aspx , 離散狀況在 5% 以下不需要調整, 在 5% ~ 30%之間, 可以利用 ALTER INDEX REORGNIZE 來進行重組, 而大於 30% 時, 可以使用 ALTER INDEX REBUILD (ONLINE = ON) 來進行索引重建.

不過若系統效能允許的狀況下, 其實也是可以直接使用 DROP INDEX, CREATE INDEX 的方式來重建的.

其他相關文章一併整理如下:

Microsoft SQL Server 2000 Index Defragmentation Best Practices
http://technet.microsoft.com/en-us/library/cc966523.aspx

sys.dm_db_index_physical_stats (Transact-SQL)
http://technet.microsoft.com/zh-tw/library/ms188917.aspx

ALTER INDEX (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms188388.aspx

Table and Index size in SQL Server
http://stackoverflow.com/questions/316831/table-and-index-size-in-sql-server

SQL Server Indexes
http://odetocode.com/articles/70.aspx