2007年9月30日 星期日

ORACLE10G--使用dbms_advisor 設定ADDM的功能

ADDM 提供效能改善建議
手動產生ADDM report
SQL> @?/rdbms/admin/addmrpt.sql
AWR 預設每60分鐘提供快照. AWR預設是自動執行, 但也能使用DBMS_WORKLOAD_REPOSITORY手動執行
MMON 會啓動ADDM 去分析二筆快照. 然後提出效能改善的建議

dbms_advisor 六個主要功能
1.create_task 開新TASK
2.set_default_task 修改工作
3.delete_task 刪除
4.execute_task 執行
5.get_task_report 取得報告
exec dbms_advisor.get_task_report( task_name IN VARCHAR2,
type IN VARCHAR2 :='TEXT',
level IN VARCHAR2 :='TYPICAL',
section IN VARCHAR2 :='ALL',
owner_name IN VARCHAR2 :=NULL
) Return clob;
type 有TEXT, XML,HTML三種值可以設定
6.set_default_task_parameter 設定工作值

相關view
DBA_ADVISOR_TASKS
DBA_ADVISOR_PARAMETERS
DBA_ADVISOR_DEF_LOG
DBA_ADVISOR_FINDINGS
DBA_ADVISOR_RECOMMENDATIONS
DBA_ADVISOR_RATIONALE
DBA_ADVISOR_ACTIONS
DBA_ADVISOR_DEF_PARAMETERS
SQL> exec dbms_advisor.set_default_task_parameter('ADDM','DBIO_EXPECTED',9000);<--DBIO_EXPECTED並不是預設參數

關閉ADDM 功能
STATISTICS_LEVEL 預設參數有三種設定值 BASIC, TYPICAL, ALL, 若要關閉ADDM功能, 請設值為BASIC

2007年9月29日 星期六

oracle -- 關於v$lock table

第一次看到v$lock 這個table,
真是一頭霧水, 原來它並不指單純的table lock 或record lock.
ID1、ID2會根據TYPE不同而儲存不同的資訊.
例如TM表示對表的更新LOCK,
TX表示對更新的ROLLBACK資訊.通常update的時候, TM和TX是一組.
TYPE
BL - Buffer hash table instance lock
CF - Control file schema global enqueue lock
CI - Cross-instance function invocation instance lock
CS - Control file schema global enqueue lock
CU - Cursor bind lock
DF - Data file instance lock
DL - Direct loader parallel index create
DM - Mount/startup db primary/secondary instance lock
DR - Distributed recovery process lock
DX - Distributed transaction entry lock
FI - SGA open-file information lock
FS - File set lock
HW - Space management operations on a specific segment lock
IN - Instance number lock
IR - Instance recovery serialization global enqueue lock
IS - Instance state lock
IV - Library cache invalidation instance lock
JQ - Job queue lock
KK - Thread kick lock
MB - Master buffer hash table instance lock
MM - Mount definition gloabal enqueue lock
MR - Media recovery lock
PF - Password file lock
PI - Parallel operation lock
PR - Process startup lock
PS - Parallel operation lock
RE - USE_ROW_ENQUEUE enforcement lock
RT - Redo thread global enqueue lock
RW - Row wait enqueue lock
SC - System commit number instance lock
SH - System commit number high water mark enqueue lock
SM - SMON lock
SN - Sequence number instance lock
SQ - Sequence number enqueue lock
SS - Sort segment lock
ST - Space transaction enqueue lock
SV - Sequence number value lock
TA - Generic enqueue lock
TD - DDL enqueue lock
TE - Extend-segment enqueue lock
TM - DML enqueue lock
TT - Temporary table enqueue lock
TX - Transaction enqueue lock
UL - User supplied lock
UN - User name lock
US - Undo segment DDL lock
WL - Being-written redo log instance lock
WS - Write-atomic-log-switch global enqueue lock

LMODE
1 - No Lock
2 - Row Share
3 - Row Exclusive
4 - Share
5 - Share Row Exclusive
6 - Exclusive

2007年9月27日 星期四

oracle10G -- create external tables 將文字檔存成table 供資料庫存取

1.文字檔emp.dat
10000001,nina,FINANCE
10000002,nina2,FINANCE2
10000003,nina3,FINANCE3
10000004,nina4,FINANCE4

2.sqlplus 操作過程
Microsoft Windows [版本 5.2.3790]
(C) 版權所有 1985-2003 Microsoft Corp。

E:\Documents and Settings\Administrator>sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期四 9月 27 22:46:32 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn / as sysdba
已連線.
建立存放文字檔的目錄. 文字檔要放在這個目錄.
SQL> create or replace directory employee_data as 'C:\employee_data'
2 ;

已建立目錄.

SQL> create table employee_ext
2 (
3 empid number(8),
4 emp_name varchar2(30),
5 dept_name varchar2(20)
6 )
7 organization external
8 (type oracle_loader
9 default directory employee_data
10 access parameters
11 (
12 records delimited by newline
13 fields terminated by ','
14 missing field values are null
15 )
16 location('emp.dat')
17 )
18 ;

已建立表格.


SQL> select * from employee_ext
2 ;

EMPID EMP_NAME DEPT_NAME
---------- ------------------------------ --------------------
10000001 nina FINANCE
10000002 nina2 FINANCE2
10000003 nina3 FINANCE3
10000004 nina4 FINANCE4


3.相關view dba_external_tables

oracle10G -- create external tables 將文字檔存成table 供資料庫存取

1.文字檔emp.dat
10000001,nina,FINANCE
10000002,nina2,FINANCE2
10000003,nina3,FINANCE3
10000004,nina4,FINANCE4

2.sqlplus 操作過程
Microsoft Windows [版本 5.2.3790]
(C) 版權所有 1985-2003 Microsoft Corp。

E:\Documents and Settings\Administrator>sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期四 9月 27 22:46:32 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

SQL> conn / as sysdba
已連線.
建立存放文字檔的目錄. 文字檔要放在這個目錄.
SQL> create or replace directory employee_data as 'C:\employee_data'
2 ;

已建立目錄.

SQL> create table employee_ext
2 (
3 empid number(8),
4 emp_name varchar2(30),
5 dept_name varchar2(20)
6 )
7 organization external
8 (type oracle_loader
9 default directory employee_data
10 access parameters
11 (
12 records delimited by newline
13 fields terminated by ','
14 missing field values are null
15 )
16 location('emp.dat')
17 )
18 ;

已建立表格.


SQL> select * from employee_ext
2 ;

EMPID EMP_NAME DEPT_NAME
---------- ------------------------------ --------------------
10000001 nina FINANCE
10000002 nina2 FINANCE2
10000003 nina3 FINANCE3
10000004 nina4 FINANCE4


3.相關view dba_external_tables

2007年9月25日 星期二

oracle 10G --關於EXPORT DUMP / IMPORT DUMP

MT table 和job同名
export dump /import dump 完成, mt table 會刪除
控制job是mcp process (the master control process)
每一個job會有一個mcp, 格式是_DMnn_
使用select * from V$process 查詢


1. expdp scott/tiger TABLES=emp ESTIMATE=STATISTICS
The data pump job will gather the estimates without actually performing the export .
2. Which view would you query to determine the user sessions attached to a data pump job
DBA_DATAPUMP_SESSIONS
3.使用expdp 只可以傳輸資料到磁碟, 不可以傳輸資料到磁帶
4.expdp help=y or impdp help=y
5.data pump 操作需要三種檔案, dump files, log files, sql files
6.data pump 是server 端操作, 所以dump file 會存在server 端, 不會存在client
7.操作範例
(1)先使用os建立該目錄E:\oracle\product\10.2.0\oradata\data_dump_file
使用sys 連線在server 端建立data dump file 環境
(1)SQL> create directory pdump_dir1 as 'E:\oracle\product\10.2.0\oradata\data_dump_file'
2 ;

已建立目錄.

(3)SQL> grant read,write on directory pdump_dir1 to scott
2 ;

順利授權.
exit

(4)在dos視窗下列舉三種指令
直接匯出不做log
expdp scott/scott directory=pdump_dir1 dumpfile=pdump_dir1.testexp01.dmp
直接匯出做log, 指定匯出dept table
expdp scott/scott directory=pdump_dir1 tables=dept dumpfile=pdump_dir1.testexp03.dmp logfile=pdump_dir1:test.log
直接匯出做log, 將該user 資料全部匯出
expdp scott/scott directory=pdump_dir1 dumpfile=pdump_dir1.testexp02.dmp logfile=pdump_dir1:test.log


Export: Release 10.2.0.1.0 - Production on 星期二, 25 9月, 2007 23:26:51

Copyright (c) 2003, 2005, Oracle. All rights reserved.

連線至: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
啟動 "SCOTT"."SYS_EXPORT_SCHEMA_01": scott/******** directory=pdump_dir1 dumpfi
le=pdump_dir1.testexp01.dmp
使用 BLOCKS 方法進行預估中...
處理物件類型 SCHEMA_EXPORT/TABLE/TABLE_DATA
總共預估使用 BLOCKS 方法: 128 KB
處理物件類型 SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
處理物件類型 SCHEMA_EXPORT/TABLE/TABLE
處理物件類型 SCHEMA_EXPORT/TABLE/INDEX/INDEX
處理物件類型 SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
處理物件類型 SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
處理物件類型 SCHEMA_EXPORT/TABLE/COMMENT
處理物件類型 SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
處理物件類型 SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
. . 已匯出 "SCOTT"."DEPT" 5.656 KB 4 個資料列

. . 已匯出 "SCOTT"."SALGRADE" 5.585 KB 5 個資料列

. . 已匯出 "SCOTT"."BONUS" 0 KB 0 個資料列

. . 已匯出 "SCOTT"."EMP" 0 KB 0 個資料列

已順利載入/取消載入主要表格 "SCOTT"."SYS_EXPORT_SCHEMA_01"
******************************************************************************
SCOTT.SYS_EXPORT_SCHEMA_01 的傾印檔集:
E:\ORACLE\PRODUCT\10.2.0\ORADATA\DATA_DUMP_FILE\PDUMP_DIR1.TESTEXP01.DMP
工作 "SCOTT"."SYS_EXPORT_SCHEMA_01" 已於 23:27:14 順利完成


E:\Documents and Settings\Administrator>

(5) datapump 相關的views select * from dba_datapump_jobs
(6)sqlfile parameter enables 你去執行 DDL 指令
(7)可以不用指定dump file 名稱, 預設名稱是expdat.dmp
(8)使用參數檔, 就是將指令寫成檔案
expdp parfile=myfile.txt
(9)job 使用ctrl + c暫停
(10)參數 包含include不包含exclude
exclude=index
include=schema:"='USER'"
include=table:"IN('USER','USER2')"
條件可下 =, like , in ,where
QUERY=scott.dept:"WHERE ID_DEPT='IT'"
(11)viewing data pump sessions
select sid,serial#
from v$session s, dba_datapump_sessions d
where s.saddr=d.saddr

我的年度目標

2000年通過mcse認證
2002年學習java
2003年通過乙級技術士認證
2004年通過oracle 9i oca
2005年通過oracle 9i ocp
2006年拿到二專學歷
2007年目標通過oracle 10G OCP <--進行中

ORACLE--spool 將sqlplus 操作過程記錄下來

conn / as sysdba
spool 20070925.log --開始記錄

select * from v$database

spool off -- 結束記錄

2007年9月20日 星期四

oracle -- 使用rman災難恢復

rman target sys/passwd@orcl nocatalog
startup force nomount
restore spfile from '備份檔' <--恢復spfile
shutdown
startup nomount
restore controlfile from '備份檔' ; <--恢復controlfile
rman > sql 'alter database mount';
rman > run{
restore database;
recover database;
}
rman > sql 'alter database open resetlogs';

oracle -- 使用rman 復原到某一時間點

c:\set NLS_DATE_FORMAT=YY/MM/DD HH24:MI:SS
rman target sys/密碼@orcl nocatalog
startup mount
run{
set until time '07/09/30 12:00:00';
restore database;
recover database;
}
rman > sql 'alter database open resetlogs';

oracle --使用rman 將受損的資料檔復原

把受損檔案復原
select * from v$recover_file

select * from V$datafile

sqlplus /nolog

conn / as sysdba

alter database datafile '資料檔名' offline

rman target sys/oracle@orcl catalog rman/rman@rman
run{
restore datafile '資料檔名';
recover datafile '資料檔名';
}

alter database datafile '資料檔名' online

2007年9月19日 星期三

oracle -- 備份注意事項

備份分三種模式
完整備份(整個資料庫備份),
增加備份(上一次備份後異動的部份),
差異備份(上一次完整備份後異動部份)

備份建議排程
週日 完整備份
週一 增加備份
週二 增加備份
週三 增加備份
週四 增加備份
週五 增加備份
週六 差異備份

oracle -- 找出不必要的索引

開始監控
alter index emp_index monitoring usage;
select * from v$object_usage;
注意monitoring 及used 兩個欄位
解除監控
alter index emp_index nomonitoring usage;

2007年9月18日 星期二

oracle -- sql 調教

set autotrace traceonly
select * from scott.dept
sql trace 報表中要避免出現
trace access (full) of 'table name' 全表格讀取.
會嚴重影響效能
及注意sql trace 報表中 n consistent gets <--所搜尋的資料筆數要越少越好.
使用 v$session_wait, v$sessoion, v$sql
找出event是'db file scattered read' 目前正在執行
全表格讀取的table
使用v$sql_plan資料表

oracle --將單一資料檔復原

1.alter database datafile '檔案路徑' offline;
2.使用os備份指令, 將該資料檔使用備份覆蓋回去.
3.recover database '檔案路徑'
4.alter database datafile '檔案路徑' online;

oracle--將單一tablespace 進行備份

1.alter tablespace user begin backup;
2.使用os備份指令, 備份該tablespace所使用資料檔
3.alter tablespce user end backup;
4.alter system archive log current;
5.alter database backup controlfile to '檔案路徑'

將ORACLE資料庫復原到受損前一刻

將ORACLE資料庫復原到受損前一刻
1.conn / as sysdba
2.startup mount
3.recover database;
對於log 指定選用AUTO,使用ARCHIVE REDO LOG 復原,
千萬不能執行ONLINE REDO LOGFILES 清除指令
4.alter database open

2007年9月15日 星期六

oracle -- 設定archive mode

一.修改參數檔
log_archive_start=true
log_archive_dest=E:\oracle\product\10.2.0\oradata\arch
log_archive_format=arch_%s%t%r.arc
二.正常關閉資料庫
conn / as sysdba
immdiate database
三. 啓動archive mode
conn / as sysdba
startup mound
alter database archivelog
alter database open
四. 取得archive log list
archive log list
五. 關閉archive
alter database noarchivelog

2007年9月13日 星期四

ORACLE--查資料庫統計資料

1.select * from v$parameter2
order by name
optimizer_mode 看使用何種模式執行統計
規則代表最好, 但不一定最快.
成本模式代表反應最快, 但不一定最好.

2.select num_rows from dba_tables
3.select num_rows from dba_tab_partitions
如果num_rows不為0, 代表有統計資料
4.取得table統計資料

SQL> execute dbms_stats.gather_table_stats('SCOTT','EMP',null,DBMS_STATS.AUTO_SAMPLE_SIZE);

已順利完成 PL/SQL 程序.

SQL>

2007年9月12日 星期三

oracle -- statspack操作範例

1.安裝statspack
sql> conn / as sysdba
sql> @%oracle_home%\rdbms\admin\spcreate.sql

2.產生資料庫快照
sql> conn perfstat/perfstat
sql> exec statpack.snap(i_snap_level => 5);
共有 0,1,5,6,7,10 預設等級是5 , 數字越大分析越細

3.分析兩個資料庫快照, 產生報告
sql> @%oracle_home%\rdbms\admin\spreport.sql

4.刪除不必要資料庫分析報告
sql> @%oracle_home%\rdbms\admin\sppurge.sql

注意幾個參數的值
Physical reads (有沒有大量異常)
Physical writees (有沒有大量異常)
Buffer Hit(要接近100%)
Library Hit(要接近100%)
Redo Nowait(要接近100%)
Top 5 Time Events (前五個最花等待時間事件)
讀取磁碟次數多的sql
Module:......................

2007年9月11日 星期二

兩台SQL資料庫同步Table的問題

1. 請先執行以下命令,並記得告訴我其回傳值
select @@ServerName

2. EXEC sp_dropserver '您的伺服器名稱', 'droplogins'
若是沒辦法刪除時,請再執行
EXEC sp_dropremotelogin '您的伺服器名稱'

3. EXEC sp_addserver '您的伺服器名稱', 'local'
您必須要重新啟動SQL Server後才會生效。

4. 再度執行以下命令,並記得告訴我其回傳值
select @@ServerName

5. 執行
EXEC SP_ADDDISTRIBUTOR @distributor='您的伺服器名稱'

6. 最後,再重新建立 Replication 。

參考資訊:
HOW TO:在不受信任網域或網際網路中執行 SQL Server 的電腦之間設定複寫
http://support.microsoft.com/?id=321822
原文出自 微軟技術社群討論區
http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=594676&SiteID=14

2007年9月10日 星期一

系統開發心得

開始撰寫系統從88年開始, 至今也7年有餘了.

前三年寫網站系統, 後四年寫ERP系統, 到今年有開始寫網站系統.

有寫過很小的程式, 如網站活動, 一個活動三五頁就搞定.

也寫過很大很大的跨國系統. 如ERP, 一個系統幾萬支程式跑不掉.

寫了那麼多年的程式, 也寫了很多很多的程式, 但永遠不外乎三個動作.

連資料庫, 讀資料, 再關資料庫.




至於開發系統心中也早有一套標準的SOP做拿捏.


可以跟大家分享.

1.開發系統一定要遵照資料庫設計的三個正規化

(前人累積的心血, 而且經過幾十年市場驗証. 有一定的重要性)

2.資料序號要開一個序號檔統一管理.

儘量不使用資料庫序號自動產生功能. 因為當資料表序號更改,

那得去修改資料表設定. 或一旦資料庫毁了, 要重灌資料庫,

或換資料庫由昂貴的MYSQL改為免費的MYSQL

你可能光查你的資料序號使用情形, 就花上不少時間.

3.常用的代碼檔, 如郵遞區號, 地址也要開一個代碼檔來管理.

序號檔及代碼檔是系統最常使用的功能. 最好優先產生成元件或寫成FUNCTION

4.接下來首先要從功能列開發(這是這個系統的靈魂所在, 功能列好不好可以決定這個系統的生死).

系統隨時會增減程式.所以功能列一定要做成動態產生.

5.接著才是開發系統的主程式.

6.預先完成一個系統流程.

動態功能列加入一個程式頁面.

程式頁面就自動產生 預設是系統最常使用的程式當預設值.

以ERP來說. 假定它有一萬支程式, 每支程式開發三天.

那完成那個系統需要三萬天. 當然不可能.

所以當它要開一個新的程式, 它會在功能列打活動管理.

那活動管理頁面基礎功能就已產生.

如新增, 修改, 刪除, 查詢... 差別可能就在連的TABLE不同而已 .

7.儘量不使用資料庫的外鍵值功能, 或太過依賴某家資料庫本身功能.

如資料庫內鍵值, 外鍵值功能, 想想如果要把兩個資料表做串連,

是用where條件方便, 還是去修改資料庫方便.

而且太過依賴資料庫功能, 會變成你的程式只能在單一資料庫上使用,

一旦換資料庫. 如mssql換成mysql. 或資料庫重灌.

那麻煩就大了

8.系統可以有列外處理. 但同一個動作, 產生的結果應該相同.

如會員資料設定, 就不能甲乙案同時進行, 甲案要求進行會員資料設定, 乙案特別就不用會員資料設

定, 那統計出來的會員資料是可以參考的, 還是真的當作參考就好.

9.程式可以擴充. 但除非必要, 儘量不要短時間內後案推翻前案. 如果太過頻繁,

那我會想那個PM大概是有問題的. 想想如果一個公司上半年要經營網站, 下半年

要經營零售業, 隔年去開始做國際貿易, 你會說那家公司有創意. 還是認為那家公司快倒了.

關於專案管理

大家從事程式開發, 大概很少只有一件工作在手上的.

或常遇到使用者要求我的比較重要, 要先做.

我也遇到過無數次. 也曾和USER鬧得臉紅脖子粗的.

但經過一番寒徹骨, 我漸漸有了心得.

長久來的習慣, 專案或程式排程我通常會如下程序去拿捏:

1.公司賺錢的先做.

2.先進先出.

這個大概沒什麼爭議, 先出現在我桌上的, 我當然先做.

3.需要時間短的先做.

一個需要三天, 一個要三個月.

我通常會先把三天的先完成. 如果一樣都要三天, 那兩件案子就流到下一關PK

4.快結束的先完成.

一件案子這次改完就結案了, 另一件案子這次改完還有要修改的項目.

那我會先把會結案的先完成, 然後結掉.

5. 如此一來, 接到案子心中大概就有譜了, 要排在什麼時間去執行.

這個方法陪我渡過無數個暴風雨.

可以提供給大家做參考.



程式修改分兩種情形:

1.BY CASE: 有BUG及緊急的我會BY CASE. 馬上修改.

2.BY 版次: 程式修改變動很大的. 我通常會多個修改項目一次修改.



程式修改的要領:

我儘量不在USER提出的第一時間修改程式.

我覺得冷靜一下或喝杯咖啡後再想一下會比較好.

我的經驗如果USER馬上說馬上改,

然後馬上通知使用者說改好了.

雖然感覺上效率很好.

到後面再改的機率通常是百分百.

所以我通常會放一下, 再想一下, 再觀察一下. 把每個環節都想通了.

才在關鍵點下手動刀, 通常這樣的結果會動到的程式部份最少.

而且也比較能讓使用者滿意.

實現 301 轉向的幾個方法

如果需要做網址轉向,一般上在 php 用 header() 實現的轉向是 302:

header("Location: http://www.newaddress.com/");

301 及 302 同樣可以做到網址的轉向,但分別在於 301 是永久的轉向,而 302 是暫時性質的轉向。這個分別對於使用者來說是沒有分別的,但對於 search engine 就有分別了。Google 推薦網站管理員當轉換網址時用 301 轉向。而以下分別是透過 .htaccess、PHP 及 ASP 實現 301 轉向的方法,而假設新 domain 是 newdomain.com:
.htaccess
在網站的根目錄建立一個 .htaccess 檔案,並加入以下內容:

RewriteEngine On
RewriteRule ^(.*)$ http://www.newdomain.com/ [R=301,L]

PHP
在 index.php 的最頂加入以下幾行:
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.newdomain.com/");
exit();
?>
ASP
在 index.asp 或 default.asp 的最頂加入以下幾行:

<%
Response.Status="301 Moved Permanently"
Response.AddHeader "Location","http://www.newdomain.com/"
Response.End
%>

資料庫的三個正規化

單一欄位中有多個有意義的值
在單一欄位中存放多個值是違反第一正規化的做法,下面這個就是很好的例子,它把多個值用逗號分開來表示:
挑食列表
人 不喜歡的食物
Jim Liver, Goat's cheese
Alice Broccoli
Norman Pheasant, Liver, Peas
以這樣的設計看來,想要知道有什麼人不喜歡某樣特定的東西是很不容易的。不過可以把這個資料表轉化成下面這種符合第一正規化的型式:
挑食列表
人 不喜歡的食物
Jim Liver
Jim Goat's cheese
Alice Broccoli
Norman Pheasant
Norman Liver
Norman Peas
[編輯] 用很多欄位來表達同一個事實
在同一個資料表裡用多個欄位來表達同一個事情也是違反第一正規化的:
個人資料
人 喜歡的顏色 不喜歡的食物 (1) 不喜歡的食物 (2) 不喜歡的食物 (3)
Jim Green Liver Goat's cheese
Alice Fuchsia Broccoli
Norman Blue Pheasant Liver Peas
Emily Yellow
就算我們能確定每個人不喜歡吃的食物最多不會超過三樣,這還是一個很糟的設計。舉例來說,我們想要知道所有不喜歡同一種食物的人的組合的話,這就不是件容易的事,因為食物有可能出現在任何一個欄位,也就是說每一次的查詢都要去檢查 9 (3 x 3) 組不同的欄位組合。

第二正規化
維基百科,自由的百科全書
跳转到: 导航, 搜尋

第二正規化正在校對翻譯。
歡迎您積極參與校對與修訂,原文在en:Second normal form。


第二正規化 (2NF) 是資料庫正規化中所使用的一種正規形式。它的規則是要求資料表裡的所有資料都要和該資料表的主鍵有相依關係;如果有哪些資料只和主鍵的一部份有關的話,就得把它們獨立出來變成另一個資料表。如果一個資料表的主鍵只有單一一個欄位的話,它就一定符合第二正規化。
一個資料表符合第二正規化若且唯若
• 它符合第一正規化
• 所有非主鍵的欄位都一定和主鍵有關
範例
有一個資料表記錄了設備元件的資訊,如下所示:
元件來源
元件 ID (主鍵) 供應商 ID (主鍵) 供應商名稱 價格 供應商住址
65 2 Stylized Parts 59.99 VA
73 2 Stylized Parts 20.00 VA
65 1 ACME Industries 69.99 CA
這個資料表的每個值都是單一值,所以它符合第一正規化。因為同一個元件有可能由不同的供應商提供,所以得把元件 ID 和供應商 ID 合在一起組成一個主鍵。
主鍵和價格之間的關係很正確:同一個元件在不同供應商有可能會有不同的報價,所以價格確實和主鍵完全相關。
另一方面,供應商的名稱和住址就只和供應商 ID 有關,這不符合第二正規化的原則。仔細看就會發現 "Stylized Parts" 這個名稱和 "VA" 這個住址重複出現了兩次;要是它改名了或是被其他公司併購了怎麼辦?這時候最好把這些資料存到第二個資料表中:
供應商
ID 名稱 住址
1 ACME Industries CA
2 Stylized Parts VA
這麼一來,原本的 "元件來源" 資料表就得要做相對應的更動:
元件來源
元件 ID (主鍵) 供應商 ID (主鍵) 價格
65 2 59.99
73 2 20.00
65 1 69.99
檢查資料表裡的每個欄位,確認它們是不是都和主鍵完全相關,這樣才能知道這個資料表是不是符合第二正規化;如果不是的話,就把那些不完全相關的欄位移到獨立的資料表裡。接下來的步驟是要確保所有不是鍵的欄位都和彼此沒有相依關係,這就叫做第三正規化。

JAVA --寫檔範例--產生big5檔案

String include_file_name="";

include_file_name="C:\\Tomcat\\webapps\\ROOT\\spadmin\\include\\includelist.inc";

BufferedWriter bufWriter = new BufferedWriter( new FileWriter(include_file_name));
bufWriter.write("<%");
bufWriter.write("@ page contentType=\"text/html; charset=utf-8\" ");
bufWriter.write("%");
bufWriter.write("> \r\n ");
ufWriter.close();

JAVA --讀寫檔範例--讀big5檔案產生utf8檔案

FileInputStream fr = null;//必需使用FileInputStream, 才能透過InputStreamReader指定編碼方式
fr = new FileInputStream("C:\\Tomcat\\webapps\\ROOT\\spadmin\\include\\spadmin.sql" );
BufferedReader bufReader = new BufferedReader( new InputStreamReader( fr,"UTF-8" ) );
String post ="";
StringBuffer defer = new StringBuffer();


while(true)
{
post = bufReader.readLine();

if (post==null) break;
if (post.length()>2){
if(post.substring(0,2).equals("--")){
post="";
}



}

defer.append(post);


}

JAVA --寫檔範例--產生utf8檔案

String include_file_name="";
include_file_name="C:\\Tomcat\\webapps\\ROOT\\spadmin\\include\\sp_check_insert_data.inc";
FileOutputStream fout = new FileOutputStream(include_file_name);
DataOutputStream dataout = new DataOutputStream(fout);
String line="";
line="<%";
line +="@ page contentType=\"text/html; charset=utf-8\" ";
line +="%";
line +="> \r\n ";
byte[] data1 = line.getBytes("UTF-8");
dataout.write(data1);
fout.close();

在SQL中隨機取得資料

MYSQL用法:
SELECT id FROM table_name order by rand() limit 10

MSSQL用法:
select top 10 * from table_name order by newid()

Oracle 用法
select * from table_name where rownum <=10 order by rowid()

修改SQL SERVER 中物件OWNER 語法

EXEC sp_changeobjectowner '[_alan.chang].LuckyVote_Member', 'dbo'

2007年9月6日 星期四

PL_SQL筆記

show all
show errors procedure wordcount
spool reprot01.txt
spool off
set serveroutput on
呼叫function
exec dbms_output.put_line(booktitle('0-596-00180-0'))

一.區塊結構
(1).
begin
.
.
end;
(2).
declare
.
begin
.
end;
(3).
declare
.
begin
.
exception
.
end;

(4)
BEGIN
<>
LOOP
LOOP
EXIT outer_loop;
END LOOP;
END LOOP;
END;

(5)
if
.
then
.
elsif
.
end if

二. raise
用法 RAISE_APPLICATION_ERROR(-20001,'總帳系統已關帳,最新關帳年月為:' || LS_CLOSE_YM1 || ',故不可刪除傳票:' || :OLD.IN_N);
或 raise l_old_time

三.EXCEPTION_INIT 的建議使用
CREATE OR REPLACE PACKAGE dynsql
IS
invalid_table_name EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_table_name,-903);
invalid_column_name EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_column_name,-904);
現在可於任何一個程式中, 用下列方式捕捉錯誤;
WHEN dynsql.invalid_column_name THEN.....

四.EXCEPTION_INIT 的建議使用之二
PACKAGE errnums
IS
en_too_young CONSTANT NUMBER := -20001;
exc_too_young EXCEPTION;
PRAGMA EXCEPTION_INIT
(exc_too_young,-20001);

en_sal_too_low CONSTANT NUMBER := -20002;
exc_sal_too_low EXCEPTION;
PRAGMA EXCEPTION INIT
(exc_sal_too_low,-20002);
END errnums;
現在可在一個程式中, 用下列方式捕捉錯誤;
PROCEDURE validate_emp (birthdate_in IN DATE)
IS
min_years CONSTANT PLS_INTEGER := 18
BEGIN
IF ADD_MONTHS(SYSDATE,min_years * 12 * -1 )< birthdate_in
THEN
RAISE_APPLICATION_ERROR
(errnums.en_too_young,'Employee must be at least' || min_years || 'old.');
END IF;
END;

oracle 9i outline sample

1. select * from armm,armd
where armm.num_armm = armd.num_armm ; 跑88秒

2.select /*+ALL_ROWS */ * from armm,armd
where armm.num_armm = armd.num_armm ; 跑60秒

3. 定義outlines 後
create or replace outline my_armm_outline
for category my_category
on
select /*+ALL_ROWS */ * from armm,armd
where armm.num_armm = armd.num_armm;

alter session set use_stored_outlines = my_category;

select * from dba_outlines;
select * from v$sql_plan;

4.直接打select * from armm,armd
where armm.num_armm = armd.num_armm ;跑52秒

oracle 9i rman sample

rman backup 全部資料庫及還原全部資料庫
1、首先使用rman前,需要建一個目錄資料庫
2、create tablespce rman datafile '/data/oradata/test/rman.dbf' size 20m;
3、create user rman identified by rman default tablespace rman temporary tablespace temp;
4、grant connect,resource,recovery_catalog_ower to rman;
以上建庫和建用戶基本成功,接著:
5、rman target sys/manager@ora8 catalog rman/rman@rman
6、register database (同步資料庫,如果資料庫做了alter database open resetlogs,就需要reset database,如果有庫結構變化,就需要
7 archive 模式下備份全部資料庫
8 c:\rman target / nocatalog
9 rman > startup mount;
10 rman > backup database;
11 rman > restore database;
12 rman > recover database;

oracle 9i logmnr sample

--指定你要從archive 或redo log file 當做分析的母體
--目前我只會從redo log file
execute dbms_logmnr_d.build(options=>dbms_logmnr_d.store_in_redo_logs);

--指定你要從哪一個redo log file開始分析
execute dbms_logmnr.add_logfile('C:\oracle\oradata\www\redo02.log', dbms_logmnr.addfile);

--開始logmnr 的功能(選你需要的其中一項執行就可以了)
execute dbms_logmnr.start_logmnr(dictfilename=>dbms_logmnr.dict_from_redo_logs );
execute dbms_logmnr.start_logmnr(dictfilename=>dbms_logmnr.committed_data_only );

--查詢logmnr 的資料
select * from v$logmnr_contents

--關閉logmnr 的功能
execute dbms_logmnr.end_logmnr

2007年9月5日 星期三

EM Editor 小設定



如果有改到程式,寫的太醜的,麻煩幫忙排列一下。
下列的設定是我個人的習慣可以參考一下。TAB=4。 (8的間隔太大了,4 剛好,2 太小了。)

2007年9月4日 星期二

javascript 判斷物件是否存在SAMPLE

<script type="text/javascript">
function No_Display() {
if (window.t1)t1.style.display='none';
if (window.t2)t2.style.display='none';
if (window.t3)t3.style.display='none';
}

</script>

正規化表示法用法

下文是好久之前找的文章,出處已經不可考了
=================================
首先讓我們看兩個特殊的符號'^'和'$'。他們的作用是分別指出一個字串的開始和結束。例子如下:

"^The":表示所有以"The"開始的字串("There","The cat"等);
"of despair$":表示所以以"of despair"結尾的字串;
"^abc$":表示開始和結尾都是"abc"的字串--呵呵,只有"abc"自己了;
"notice":表示任何包含"notice"的字串。

象最後那個例子,如果你不使用兩個特殊字元,你就在表示要查找的串在被查找串的任意部分--你並
不把它定位在某一個頂端。

其他還有'*','+'和'?'這三個符號,表示一個或一序列字元重復出現的次數。它們分別表示"沒有或
更多","一次或更多"還有"沒有或一次"。下面是幾個例子:

"ab*":表示一個字串有一個a後面跟著零個或若干個b。("a", "ab", "abbb",……);
"ab+":表示一個字串有一個a後面跟著至少一個b或者更多;
"ab?":表示一個字串有一個a後面跟著零個或者一個b;
"a?b+$":表示在字串的末尾有零個或一個a跟著一個或幾個b。

你也可以使用範圍,用大括弧括起,用以表示重復次數的範圍。

"ab{2}":表示一個字串有一個a跟著2個b("abb");
"ab{2,}":表示一個字串有一個a跟著至少2個b;
"ab{3,5}":表示一個字串有一個a跟著3到5個b。

請注意,你必須指定範圍的下限(如:"{0,2}"而不是"{,2}")。還有,你可能注意到了,'*','+'和
'?'相當於"{0,}","{1,}"和"{0,1}"。
還有一個'¦',表示"或"操作:

"hi¦hello":表示一個字串裏有"hi"或者"hello";
"(b¦cd)ef":表示"bef"或"cdef";
"(a¦b)*c":表示一串"a""b"混合的字串後面跟一個"c";

'.'可以替代任何字元:

"a.[0-9]":表示一個字串有一個"a"後面跟著一個任意字元和一個數位;
"^.{3}$":表示有任意三個字元的字串(長度為3個字元);

方括號表示某些字元允許在一個字串中的某一特定位置出現:

"[ab]":表示一個字串有一個"a"或"b"(相當於"a¦b");
"[a-d]":表示一個字串包含小寫的'a'到'd'中的一個(相當於"a¦b¦c¦d"或者"[abcd]");
"^[a-zA-Z]":表示一個以字母開頭的字串;
"[0-9]%":表示一個百分號前有一位元的數位;
",[a-zA-Z0-9]$":表示一個字串以一個逗號後面跟著一個字母或數位結束。

你也可以在方括號裏用'^'表示不希望出

ASP 網路上下載遠端圖檔

URL = "http://www.yahoo.com.tw/"& strGUID & ".jpg"
Set objXMLHTTP = CreateObject("Microsoft.XMLHTTP")
objXMLHTTP.Open "GET", URL, false
objXMLHTTP.Send

Set objStream = CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
Pic = objXMLHTTP.responseBody

Set objStream = Nothing
Blob2File mypage,"C:\taiwan.gif"
Set objXMLHTTP = Nothing

ASP ADODB Stream SAMPLE

'寫圖檔
Sub Blob2File(BlobX,strFileName)
Set objStream = CreateObject("ADODB.Stream")
objStream.open
objStream.Type = 1
objStream.Write BlobX
objStream.SaveToFile strFileName,2
Set objStream = Nothing
End Sub

'寫文字檔
Sub SaveToFile(ByVal strBody,ByVal File)
Dim objStream
On Error Resume Next
Set objStream = CreateObject("ADODB.Stream")
If Err.Number=-2147221005 Then
msgbox "您的主机不支持ADODB.Stream,不能使用本程序"
Err.Clear

End If
With objStream
.Type = 2
.Open
.Charset = "UTF-8"
.Position = objStream.Size
.WriteText = strBody
.SaveToFile File,2
.Close
End With
Set objStream = Nothing
End Sub

SQLSERVER-StrGUID資料庫欄位設法

ASP縮成預設大小的圖

'開始縮成預設大小的圖
Set Image = Server.CreateObject("AspImage.Image")
Image.AutoSize = false
Image.LoadBlob FileBody, 1
Image.resize 100,200
Response.ContentType = "image/jpeg"
FileBody = Image.Image
Set Image = Nothing

asp去除HTML標籤

'###############################
' 去除HTML標籤
'###############################
Function reHTML(strText)


strText = Replace(strText, "<br>", "")
strText = Replace(strText, "<Br>", "")
strText = Replace(strText, "<bR>", "")
strText = Replace(strText, "<BR>", "")
strText = Replace(strText, " ", "")
strText = Replace(strText, vbCrLf, "")
strText = Replace(strText, chr(10), "")
strText = Replace(strText, chr(13), "")
strText = Replace(strText, "'", "\'")
strText = Replace(strText, " ", "")
strText = Replace(strText, ",", ",")
strText = Replace(strText, ".", "。")

reHTML = strText

End Function

ASP指定網頁語系

utf8
<%@LANGUAGE=VBSCRIPT CODEPAGE=65001%>
<%
Session.CodePage = 65001
Response.CodePage = 65001
Response.CharSet = "utf-8"
%>
big5
<%@LANGUAGE=VBSCRIPT CODEPAGE=950%>
<%
Session.CodePage = 950
Response.CodePage = 950
Response.CharSet = "BIG5"
%>

正規化表示法範例

'正規化表示法範例 適用JAVA版本
String regEx = "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";
Pattern p=Pattern.compile(regEx);
Matcher m=p.matcher(post);
boolean result=m.find();
System.out.println(m.find());
while(m.find()){
System.out.println(m.group());
}
================================================
'正規化表示法範例 適用ASP版本
範例 [0-9.] 找 0-9及.
[^0-9.] 找0-9及. 以外的

set objRegExp= New RegExp
objRegExp.Global = True
objRegExp.IgnoreCase=True
objRegExp.Pattern="(![A-Z,0-9, ])"
tmp=objRegExp.replace(tmp,"")
set objRegExp=Nothing