Hibernate映射類(lèi)型分為兩種:內置映射類(lèi)型和客戶(hù)化映射類(lèi)型。內置映射類(lèi)型負責把一些常見(jiàn)的Java類(lèi)型映射到相應的SQL類(lèi)型;此外,Hibernate還允許用戶(hù)實(shí)現UserType或CompositeUserType接口,來(lái)靈活地定制客戶(hù)化映射類(lèi)型??蛻?hù)化類(lèi)型能夠把用戶(hù)定義的Java類(lèi)型映射到數據庫表的相應字段。
一、Hibernate的內置映射類(lèi)型
1、Java基本類(lèi)型的Hibernate映射類(lèi)型
| Hibernate映射類(lèi)型 | Java類(lèi)型 | 標準SQL類(lèi)型 | 大小和取值范圍 |
| integer或者int | int或者java.lang.Integer | INTEGER | 4字節 |
| long | long Long | BIGINT | 8字節 |
| short | short Short | SMALLINT | 2字節 |
| byte | byte Byte | TINYINT | 1字節 |
| float | float Float | FLOAT | 4字節 |
| double | double Double | DOUBLE | 8字節 |
| big_decimal | java.math.BigDecimal | NUMERIC | NUMERIC(8,2)8位 |
| character | char Character String | CHAR(1) | 定長(cháng)字符 |
| string | String | VARCHAR | 變長(cháng)字符串 |
| boolean | boolean Boolean | BIT | 布爾類(lèi)型 |
| yes_no | boolean Boolean | CHAR(1) (Y-N) | 布爾類(lèi)型 |
| true_false | boolean Boolean | CHAR(1) (T-F) | 布爾類(lèi)型 |
2、Java時(shí)間和日期類(lèi)型的Hibernate映射
| 映射類(lèi)型 | Java類(lèi)型 | 標準SQL類(lèi)型 | 描述 |
| date | util.Date或者sql.Date | DATE | YYYY-MM-DD |
| time | Date Time | TIME | HH:MM:SS |
| timestamp | Date Timestamp | TIMESTAMP | YYYYMMDDHHMMSS |
| calendar | calendar | TIMESTAMP | YYYYMMDDHHMMSS |
| calendar_date | calendar | DATE | YYYY-MM-DD |
3、Java大對象類(lèi)型的Hibernate映射類(lèi)型
| 映射類(lèi)型 | Java類(lèi)型 | 標準SQL類(lèi)型 | MySQL類(lèi)型 | Oracle類(lèi)型 |
| binary | byte[] | VARBINARY(或BLOB) | BLOB | BLOB |
| text | String | CLOB | TEXT | CLOB |
| serializable | Serializable接口任意實(shí)現類(lèi) | VARBINARY(或BLOB) | BLOB | BLOB |
| clob | java.sql.Clob | CLOB | TEXT | CLOB |
| blob | java.sql.Blob | BLOB | BLOB | BLOB |
在程序中通過(guò)Hibernate來(lái)保存java.sql.Clob或者java.sql.Blob實(shí)例時(shí),必須包含兩個(gè)步驟:
l 在一個(gè)數據庫事務(wù)中先保存一個(gè)空的Blob或Clob實(shí)例。
l 接著(zhù)鎖定這條記錄,更新上面保存的Blob或Clob實(shí)例,把二進(jìn)制數據或文本數據寫(xiě)到Blob或Clob實(shí)例中。
(1)整合簡(jiǎn)單,無(wú)關(guān)聯(lián)的數據庫訪(fǎng)問(wèn):
如果你有幾個(gè)簡(jiǎn)單的數據庫查詢(xún)語(yǔ)句,你可以把它們整合到一個(gè)查詢(xún)中(即使它們之間沒(méi)有關(guān)系)
(2)刪除重復記錄:
最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(3)用TRUNCATE替代DELETE:
當刪除表中的記錄時(shí),在通常情況下, 回滾段(rollback segments ) 用來(lái)存放可以被恢復的信息. 如果你沒(méi)有COMMIT事務(wù),ORACLE會(huì )將數據恢復到刪除之前的狀態(tài)(準確地說(shuō)是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時(shí), 回滾段不再存放任何可被恢復的信息.當命令運行后,數據不能被恢復.因此很少的資源被調用,執行時(shí)間也會(huì )很短. (譯者按: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)
(4)選擇最有效率的表名順序(只在基于規則的優(yōu)化器中有效):
ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫(xiě)在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個(gè)表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個(gè)以上的表連接查詢(xún), 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個(gè)被其他表所引用的表.
(5)WHERE子句中的連接順序.:
ORACLE采用自下而上的順序解析WHERE子句,根據這個(gè)原理,表之間的連接必須寫(xiě)在其他WHERE條件之前, 那些可以過(guò)濾掉最大數量記錄的條件必須寫(xiě)在WHERE子句的末尾.
(6)SELECT子句中避免使用 ‘ * ‘:
ORACLE在解析的過(guò)程中, 會(huì )將’*’ 依次轉換成所有的列名, 這個(gè)工作是通過(guò)查詢(xún)數據字典完成的, 這意味著(zhù)將耗費更多的時(shí)間
(7)減少訪(fǎng)問(wèn)數據庫的次數:
ORACLE在內部執行了許多工作: 解析SQL語(yǔ)句, 估算索引的利用率, 綁定變量 , 讀數據塊等;
(8)在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次數據庫訪(fǎng)問(wèn)的檢索數據量 ,建議值為200
(9)使用DECODE函數來(lái)減少處理時(shí)間:
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.
(11) 用Where子句替換HAVING子句:
避免使用HAVING子句, HAVING 只會(huì )在檢索出所有記錄之后才對結果集進(jìn)行過(guò)濾. 這個(gè)處理需要排序,總計等操作. 如果能通過(guò)WHERE子句限制記錄的數目,那就能減少這方面的開(kāi)銷(xiāo). (非oracle中)on、where、having這三個(gè)都可以加條件的子句中,on是最先執行,where次之,having最后,因為on是先把不符合條件的記錄過(guò)濾后才進(jìn)行統計,它就可以減少中間運算要處理的數據,按理說(shuō)應該速度是最快的,where也應該比having快點(diǎn)的,因為它過(guò)濾數據后才進(jìn)行sum,在兩個(gè)表聯(lián)接時(shí)才用on的,所以在一個(gè)表的時(shí)候,就剩下where跟having比較了。在這單表查詢(xún)統計的情況下,如果要過(guò)濾的條件沒(méi)有涉及到要計算字段,那它們的結果是一樣的,只是where可以使用rushmore技術(shù),而having就不能,在速度上后者要慢如果要涉及到計算的字段,就表示在沒(méi)計算之前,這個(gè)字段的值是不確定的,根據上篇寫(xiě)的工作流程,where的作用時(shí)間是在計算之前就完成的,而having就是在計算后才起作用的,所以在這種情況下,兩者的結果會(huì )不同。在多表聯(lián)接查詢(xún)時(shí),on比where更早起作用。系統首先根據各個(gè)表之間的聯(lián)接條件,把多個(gè)表合成一個(gè)臨時(shí)表后,再由where進(jìn)行過(guò)濾,然后再計算,計算完后再由having進(jìn)行過(guò)濾。由此可見(jiàn),要想過(guò)濾條件起到正確的作用,首先要明白這個(gè)條件應該在什么時(shí)候起作用,然后再決定放在那里
(12) 減少對表的查詢(xún):
在含有子查詢(xún)的SQL語(yǔ)句中,要特別注意減少對表的查詢(xún).例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
(13) 通過(guò)內部函數提高SQL效率.:
復雜的SQL往往犧牲了執行效率. 能夠掌握上面的運用函數解決問(wèn)題的方法在實(shí)際工作中是非常有意義的
(14) 使用表的別名(Alias):
當在SQL語(yǔ)句中連接多個(gè)表時(shí), 請使用表的別名并把別名前綴于每個(gè)Column上.這樣一來(lái),就可以減少解析的時(shí)間并減少那些由Column歧義引起的語(yǔ)法錯誤.
(15) 用EXISTS替代IN、用NOT EXISTS替代NOT IN:
在許多基于基礎表的查詢(xún)中,為了滿(mǎn)足一個(gè)條件,往往需要對另一個(gè)表進(jìn)行聯(lián)接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢(xún)的效率. 在子查詢(xún)中,NOT IN子句將執行一個(gè)內部的排序和合并. 無(wú)論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢(xún)中的表執行了一個(gè)全表遍歷). 為了避免使用NOT IN ,我們可以把它改寫(xiě)成外連接(Outer Joins)或NOT EXISTS.
例子:
(高效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
(低效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)
(16) 識別’低效執行’的SQL語(yǔ)句:
雖然目前各種關(guān)于SQL優(yōu)化的圖形化工具層出不窮,但是寫(xiě)出自己的SQL工具來(lái)解決問(wèn)題始終是一個(gè)最好的方法:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
(17) 用索引提高效率:
索引是表的一個(gè)概念部分,用來(lái)提高檢索數據的效率,ORACLE使用了一個(gè)復雜的自平衡B-tree結構. 通常,通過(guò)索引查詢(xún)數據比全表掃描要快. 當ORACLE找出執行查詢(xún)和Update語(yǔ)句的最佳路徑時(shí), ORACLE優(yōu)化器將使用索引. 同樣在聯(lián)結多個(gè)表時(shí)使用索引也可以提高效率. 另一個(gè)使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證.。那些LONG或LONG RAW數據類(lèi)型, 你可以索引幾乎所有的列. 通常, 在大型表中使用索引特別有效. 當然,你也會(huì )發(fā)現, 在掃描小表時(shí),使用索引同樣能提高效率. 雖然使用索引能得到查詢(xún)效率的提高,但是我們也必須注意到它的代價(jià). 索引需要空間來(lái)存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時(shí), 索引本身也會(huì )被修改. 這意味著(zhù)每條記錄的INSERT , DELETE , UPDATE將為此多付出4 , 5 次的磁盤(pán)I/O . 因為索引需要額外的存儲空間和處理,那些不必要的索引反而會(huì )使查詢(xún)反應時(shí)間變慢.。定期的重構索引是有必要的.:
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
18) 用EXISTS替換DISTINCT:
當提交一個(gè)包含一對多表信息(比如部門(mén)表和雇員表)的查詢(xún)時(shí),避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換, EXISTS 使查詢(xún)更為迅速,因為RDBMS核心模塊將在子查詢(xún)的條件一旦滿(mǎn)足后,立刻返回結果. 例子:
(低效):
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO
(高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
(19) sql語(yǔ)句用大寫(xiě)的;因為oracle總是先解析sql語(yǔ)句,把小寫(xiě)的字母轉換成大寫(xiě)的再執行
(20) 在java代碼中盡量少用連接符“+”連接字符串!
(21) 避免在索引列上使用NOT 通常,
我們要避免在索引列上使用NOT, NOT會(huì )產(chǎn)生在和在索引列上使用函數相同的影響. 當ORACLE”遇到”NOT,他就會(huì )停止使用索引轉而執行全表掃描.
(22) 避免在索引列上使用計算.
WHERE子句中,如果索引列是函數的一部分.優(yōu)化器將不使用索引而使用全表掃描.
舉例:
低效:
SELECT … FROM DEPT WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
(23) 用>=替代>
高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
兩者的區別在于, 前者DBMS將直接跳到第一個(gè)DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個(gè)DEPT大于3的記錄.
(24) 用UNION替換OR (適用于索引列)
通常情況下, 用UNION替換WHERE子句中的OR將會(huì )起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規則只針對多個(gè)索引列有效. 如果有column沒(méi)有被索引, 查詢(xún)效率可能會(huì )因為你沒(méi)有選擇OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你堅持要用OR, 那就需要返回記錄最少的索引列寫(xiě)在最前面.
(25) 用IN來(lái)替換OR
這是一條簡(jiǎn)單易記的規則,但是實(shí)際的執行效果還須檢驗,在ORACLE8i下,兩者的執行路徑似乎是相同的.
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);
(26) 避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以為空的列,ORACLE將無(wú)法使用該索引.對于單列索引,如果列包含空值,索引中將不存在此記錄. 對于復合索引,如果每個(gè)列都為空,索引中同樣不存在此記錄. 如果至少有一個(gè)列不為空,則記錄存在于索引中.舉例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一條記錄的A,B值為(123,null) , ORACLE將不接受下一條具有相同A,B值(123,null)的記錄(插入). 然而如果所有的索引列都為空,ORACLE將認為整個(gè)鍵值為空而空不等于空. 因此你可以插入1000 條具有相同鍵值的記錄,當然它們都是空! 因為空值不存在于索引列中,所以WHERE子句中對索引列進(jìn)行空值比較將使ORACLE停用該索引.
低效: (索引失效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;
(27) 總是使用索引的第一個(gè)列:
如果索引是建立在多個(gè)列上, 只有在它的第一個(gè)列(leading column)被where子句引用時(shí),優(yōu)化器才會(huì )選擇使用該索引. 這也是一條簡(jiǎn)單而重要的規則,當僅引用索引的第二個(gè)列時(shí),優(yōu)化器使用了全表掃描而忽略了索引
28) 用UNION-ALL 替換UNION ( 如果有可能的話(huà)):
當SQL 語(yǔ)句需要UNION兩個(gè)查詢(xún)結果集合時(shí),這兩個(gè)結果集合會(huì )以UNION-ALL的方式被合并, 然后在輸出最終結果前進(jìn)行排序. 如果用UNION ALL替代UNION, 這樣排序就不是必要了. 效率就會(huì )因此得到提高. 需要注意的是,UNION ALL 將重復輸出兩個(gè)結果集合中相同記錄. 因此各位還是要從業(yè)務(wù)需求分析使用UNION ALL的可行性. UNION 將對結果集合排序,這個(gè)操作會(huì )使用到SORT_AREA_SIZE這塊內存. 對于這塊內存的優(yōu)化也是相當重要的. 下面的SQL可以用來(lái)查詢(xún)排序的消耗量
低效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95’
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95’
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95’
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = ’31-DEC-95’
(29) 用WHERE替代ORDER BY:
ORDER BY 子句只在兩種嚴格的條件下使用索引.
ORDER BY中所有的列必須包含在相同的索引中并保持在索引中的排列順序.
ORDER BY中所有的列必須定義為非空.
WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.
例如:
表DEPT包含以下列:
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE
高效: (使用索引)
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0
(30) 避免改變索引列的類(lèi)型.:
當比較不同數據類(lèi)型的數據時(shí), ORACLE自動(dòng)對列進(jìn)行簡(jiǎn)單的類(lèi)型轉換.
假設 EMPNO是一個(gè)數值類(lèi)型的索引列.
SELECT … FROM EMP WHERE EMPNO = ‘123’
實(shí)際上,經(jīng)過(guò)ORACLE類(lèi)型轉換, 語(yǔ)句轉化為:
SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123’)
幸運的是,類(lèi)型轉換沒(méi)有發(fā)生在索引列上,索引的用途沒(méi)有被改變.
現在,假設EMP_TYPE是一個(gè)字符類(lèi)型的索引列.
SELECT … FROM EMP WHERE EMP_TYPE = 123
這個(gè)語(yǔ)句被ORACLE轉換為:
SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123
因為內部發(fā)生的類(lèi)型轉換, 這個(gè)索引將不會(huì )被用到! 為了避免ORACLE對你的SQL進(jìn)行隱式的類(lèi)型轉換, 最好把類(lèi)型轉換用顯式表現出來(lái). 注意當字符和數值比較時(shí), ORACLE會(huì )優(yōu)先轉換數值類(lèi)型到字符類(lèi)型
(31) 需要當心的WHERE子句:
某些SELECT 語(yǔ)句中的WHERE子句不使用索引. 這里有一些例子.
在下面的例子里, (1)‘!=’ 將不使用索引. 記住, 索引只能告訴你什么存在于表中, 而不能告訴你什么不存在于表中. (2) ‘||’是字符連接函數. 就象其他函數那樣, 停用了索引. (3) ‘+’是數學(xué)函數. 就象其他數學(xué)函數那樣, 停用了索引. (4)相同的索引列不能互相比較,這將會(huì )啟用全表掃描.
(32) a. 如果檢索數據量超過(guò)30%的表中記錄數.使用索引將沒(méi)有顯著(zhù)的效率提高.
b. 在特定情況下, 使用索引也許會(huì )比全表掃描慢, 但這是同一個(gè)數量級上的區別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!
(33) 避免使用耗費資源的操作:
帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語(yǔ)句會(huì )啟動(dòng)SQL引擎
執行耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序. 通常, 帶有UNION, MINUS , INTERSECT的SQL語(yǔ)句都可以用其他方式重寫(xiě). 如果你的數據庫的SORT_AREA_SIZE調配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 畢竟它們的可讀性很強
(34) 優(yōu)化GROUP BY:
提高GROUP BY 語(yǔ)句的效率, 可以通過(guò)將不需要的記錄在GROUP BY 之前過(guò)濾掉.下面兩個(gè)查詢(xún)返回相同結果但第二個(gè)明顯就快了許多.
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP by JOB
HAVING JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT’
OR JOB = ‘MANAGER’
GROUP by JOB
7、說(shuō)明:在線(xiàn)視圖查詢(xún)(表名1:a )
select * from (SELECT a,b,c FROM a) T where t.a > 1;
9、說(shuō)明:in 的使用方法
select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)
12、說(shuō)明:日程安排提前五分鐘提醒
SQL: select * from 日程安排 where datediff(‘minute’,f開(kāi)始時(shí)間,getdate())>5
13、說(shuō)明:一條sql 語(yǔ)句搞定數據庫分頁(yè)
select top 10 b.* from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主鍵字段 = a.主鍵字段 order by a.排序字段
具體實(shí)現:
關(guān)于數據庫分頁(yè):
declare @start int,@end int
@sql nvarchar(600)
set @sql=’select top’+str(@end-@start+1)+’+from T where rid not in(select top’+str(@str-1)+’Rid from T where Rid>-1)’
exec sp_executesql @sql
注意:在top后不能直接跟一個(gè)變量,所以在實(shí)際應用中只有這樣的進(jìn)行特殊的處理。Rid為一個(gè)標識列,如果top后還有具體的字段,這樣做是非常有好處的。因為這樣可以避免 top的字段如果是邏輯索引的,查詢(xún)的結果后實(shí)際表中的不一致(邏輯索引中的數據有可能和數據表中的不一致,而查詢(xún)時(shí)如果處在索引則首先查詢(xún)索引)
14、說(shuō)明:前10條記錄
select top 10 * form table1 where 范圍
17、說(shuō)明:隨機取出10條數據
select top 10 * from tablename order by newid()
18、說(shuō)明:隨機選擇記錄
select newid()
alter table tablename
–添加一個(gè)自增列
add column_b int identity(1,1)
delete from tablename where column_b not in(
select max(column_b) from tablename group by column1,column2,…)
alter table tablename drop column column_b
20、說(shuō)明:列出數據庫里所有的表名
select name from sysobjects where type=’U’ // U代表用戶(hù)
21、說(shuō)明:列出表里的所有的列名
select name from syscolumns where id=object_id(‘TableName’)
TRUNCATE TABLE table1
1、1=1,1=2的使用,在SQL語(yǔ)句組合時(shí)用的較多
“where 1=1” 是表示選擇全部 “where 1=2”全部不選,
如:
if @strWhere !=”
begin
set @strSQL = ‘select count(*) as Total from [' + @tblName + '] where ‘ + @strWhere
end
else
begin
set @strSQL = ‘select count(*) as Total from [' + @tblName + ']‘
end
我們可以直接寫(xiě)成
錯誤!未找到目錄項。
set @strSQL = ‘select count(*) as Total from [' + @tblName + '] where 1=1 安定 ‘+ @strWhere 2、收縮數據庫
–重建索引
DBCC REINDEX
DBCC INDEXDEFRAG
–收縮數據和日志
DBCC SHRINKDB
DBCC SHRINKFILE
3、壓縮數據庫
dbcc shrinkdatabase(dbname)
4、轉移數據庫給新用戶(hù)以已存在用戶(hù)權限
exec sp_change_users_login ‘update_one’,'newname’,'oldname’
go
5、檢查備份集
RESTORE VERIFYONLY from disk=’E:\dvbbs.bak’
7、日志清除
SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
@MaxMinutes INT,
@NewSize INT
USE tablename — 要操作的數據庫名
SELECT @LogicalFileName = ‘tablename_log’, — 日志文件名
@MaxMinutes = 10, — Limit on time allowed to wrap log.
@NewSize = 1 — 你想設定的日志文件的大小(M)
Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size
FROM sysfiles
WHERE name = @LogicalFileName
SELECT ‘Original Size of ‘ + db_name() + ‘ LOG is ‘ +
CONVERT(VARCHAR(30),@OriginalSize) + ‘ 8K pages or ‘ +
CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + ‘MB’
FROM sysfiles
WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
(DummyColumn char (8000) not null)
DECLARE @Counter INT,
@StartTime DATETIME,
@TruncLog VARCHAR(255)
SELECT @StartTime = GETDATE(),
@TruncLog = ‘BACKUP LOG ‘ + db_name() + ‘ WITH TRUNCATE_ONLY’
DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
– Wrap the log if necessary.
WHILE @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) — time has not expired
AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)
AND (@OriginalSize * 8 /1024) > @NewSize
BEGIN — Outer loop.
SELECT @Counter = 0
WHILE ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
BEGIN — update
INSERT DummyTrans VALUES (‘Fill Log’) DELETE DummyTrans
SELECT @Counter = @Counter + 1
END
EXEC (@TruncLog)
END
SELECT ‘Final Size of ‘ + db_name() + ‘ LOG is ‘ +
CONVERT(VARCHAR(30),size) + ‘ 8K pages or ‘ +
CONVERT(VARCHAR(30),(size*8/1024)) + ‘MB’
FROM sysfiles
WHERE name = @LogicalFileName
DROP TABLE DummyTrans
SET NOCOUNT OFF
8、說(shuō)明:更改某個(gè)表
exec sp_changeobjectowner ‘tablename’,'dbo’
CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
@OldOwner as NVARCHAR(128),
@NewOwner as NVARCHAR(128)
AS
DECLARE @Name as NVARCHAR(128)
DECLARE @Owner as NVARCHAR(128)
DECLARE @OwnerName as NVARCHAR(128)
DECLARE curObject CURSOR FOR
select ‘Name’ = name,
‘Owner’ = user_name(uid)
from sysobjects
where user_name(uid)=@OldOwner
order by name
OPEN curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN
if @Owner=@OldOwner
begin
set @OwnerName = @OldOwner + ‘.’ + rtrim(@Name)
exec sp_changeobjectowner @OwnerName, @NewOwner
end
– select @name,@NewOwner,@OldOwner
FETCH NEXT FROM curObject INTO @Name, @Owner
END
close curObject
deallocate curObject
GO
10、SQL SERVER中直接循環(huán)寫(xiě)入數據
declare @i int
set @i=1
while @i<30
begin
insert into test (userid) values(@i)
set @i=@i+1
end
案例:
有如下表,要求就裱中所有沒(méi)有及格的成績(jì),在每次增長(cháng)0.1的基礎上,使他們剛好及格:
Name score
Zhangshan 80
Lishi 59
Wangwu 50
Songquan 69
while((select min(score) from tb_table)<60)
begin
update tb_table set score =score*1.01
where score<60
if (select min(score) from tb_table)>60
break
else
continue
end
2.數據庫加密:
select encrypt(‘原始密碼’)
select pwdencrypt(‘原始密碼’)
select pwdcompare(‘原始密碼’,'加密后密碼’) = 1–相同;否則不相同 encrypt(‘原始密碼’)
select pwdencrypt(‘原始密碼’)
select pwdcompare(‘原始密碼’,'加密后密碼’) = 1–相同;否則不相同
4.查看硬盤(pán)分區:
EXEC master..xp_fixeddrives
7.記錄搜索:
開(kāi)頭到N條記錄
Select Top N * From 表
——————————-
N到M條記錄(要有主索引ID)
Select Top M-N * From 表 Where ID in (Select Top M ID From 表) Order by ID Desc
———————————-
N到結尾記錄
Select Top N * From 表 Order by ID Desc
案例
例如1:一張表有一萬(wàn)多條記錄,表的第一個(gè)字段 RecID 是自增長(cháng)字段, 寫(xiě)一個(gè)SQL語(yǔ)句, 找出表的第31到第40個(gè)記錄。
select top 10 recid from A where recid not in(select top 30 recid from A)
分析:如果這樣寫(xiě)會(huì )產(chǎn)生某些問(wèn)題,如果recid在表中存在邏輯索引。
select top 10 recid from A where……是從索引中查找,而后面的select top 30 recid from A則在數據表中查找,這樣由于索引中的順序有可能和數據表中的不一致,這樣就導致查詢(xún)到的不是本來(lái)的欲得到的數據。
解決方案
1, 用order by select top 30 recid from A order by ricid 如果該字段不是自增長(cháng),就會(huì )出現問(wèn)題
2, 在那個(gè)子查詢(xún)中也加條件:select top 30 recid from A where recid>-1
例2:查詢(xún)表中的最后以條記錄,并不知道這個(gè)表共有多少數據,以及表結構。
set @s = ‘select top 1 * from T where pid not in (select top ‘ + str(@count-1) + ‘ pid from T)’
print @s exec sp_executesql @s
9:獲取當前數據庫中的所有用戶(hù)表
select Name from sysobjects where xtype=’u’ and status>=0
10:獲取某一個(gè)表的所有字段
select name from syscolumns where id=object_id(‘表名’)
select name from syscolumns where id in (select id from sysobjects where type = ‘u’ and name = ‘表名’)
兩種方式的效果相同
11:查看與某一個(gè)表相關(guān)的視圖、存儲過(guò)程、函數
select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like ‘%表名%’
12:查看當前數據庫中所有存儲過(guò)程
select name as 存儲過(guò)程名稱(chēng) from sysobjects where xtype=’P’
13:查詢(xún)用戶(hù)創(chuàng )建的所有數據庫
select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name=’sa’)
或者
select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0×01
14:查詢(xún)某一個(gè)表的字段和數據類(lèi)型
select column_name,data_type from information_schema.columns
where table_name = ‘表名’
15:不同服務(wù)器數據庫之間的數據操作
–創(chuàng )建鏈接服務(wù)器
exec sp_addlinkedserver ‘ITSV ‘, ‘ ‘, ‘SQLOLEDB ‘, ‘遠程服務(wù)器名或ip地址 ‘
exec sp_addlinkedsrvlogin ‘ITSV ‘, ‘false ‘,null, ‘用戶(hù)名 ‘, ‘密碼 ‘
–查詢(xún)示例
select * from ITSV.數據庫名.dbo.表名
–導入示例
select * into 表 from ITSV.數據庫名.dbo.表名
–以后不再使用時(shí)刪除鏈接服務(wù)器
exec sp_dropserver ‘ITSV ‘, ‘droplogins ‘
–連接遠程/局域網(wǎng)數據(openrowset/openquery/opendatasource)
–1、openrowset
–查詢(xún)示例
select * from openrowset( ‘SQLOLEDB ‘, ‘sql服務(wù)器名 ‘; ‘用戶(hù)名 ‘; ‘密碼 ‘,數據庫名.dbo.表名)
–生成本地表
select * into 表 from openrowset( ‘SQLOLEDB ‘, ‘sql服務(wù)器名 ‘; ‘用戶(hù)名 ‘; ‘密碼 ‘,數據庫名.dbo.表名)
–把本地表導入遠程表
insert openrowset( ‘SQLOLEDB ‘, ‘sql服務(wù)器名 ‘; ‘用戶(hù)名 ‘; ‘密碼 ‘,數據庫名.dbo.表名)
select *from 本地表
–更新本地表
update b
set b.列A=a.列A
from openrowset( ‘SQLOLEDB ‘, ‘sql服務(wù)器名 ‘; ‘用戶(hù)名 ‘; ‘密碼 ‘,數據庫名.dbo.表名)as a inner join 本地表 b
on a.column1=b.column1
–openquery用法需要創(chuàng )建一個(gè)連接
–首先創(chuàng )建一個(gè)連接創(chuàng )建鏈接服務(wù)器
exec sp_addlinkedserver ‘ITSV ‘, ‘ ‘, ‘SQLOLEDB ‘, ‘遠程服務(wù)器名或ip地址 ‘
–查詢(xún)
select *
FROM openquery(ITSV, ‘SELECT * FROM 數據庫.dbo.表名 ‘)
–把本地表導入遠程表
insert openquery(ITSV, ‘SELECT * FROM 數據庫.dbo.表名 ‘)
select * from 本地表
–更新本地表
update b
set b.列B=a.列B
FROM openquery(ITSV, ‘SELECT * FROM 數據庫.dbo.表名 ‘) as a
inner join 本地表 b on a.列A=b.列A
–3、opendatasource/openrowset
SELECT *
FROM opendatasource( ‘SQLOLEDB ‘, ‘Data Source=ip/ServerName;User ID=登陸名;Password=密碼 ‘ ).test.dbo.roy_ta
–把本地表導入遠程表
insert opendatasource( ‘SQLOLEDB ‘, ‘Data Source=ip/ServerName;User ID=登陸名;Password=密碼 ‘).數據庫.dbo.表名
select * from 本地表
SQL Server基本函數
SQL Server基本函數
1.字符串函數 長(cháng)度與分析用
1,datalength(Char_expr) 返回字符串包含字符數,但不包含后面的空格
2,substring(expression,start,length) 取子串,字符串的下標是從“1”,start為起始位置,length為字符串長(cháng)度,實(shí)際應用中以len(expression)取得其長(cháng)度
3,right(char_expr,int_expr) 返回字符串右邊第int_expr個(gè)字符,還用left于之相反
4,isnull( check_expression , replacement_value )如果check_expression為空,則返回replacement_value的值,不為空,就返回check_expression字符操作類(lèi)
5,Sp_addtype 自定義數據類(lèi)型
例如:EXEC sp_addtype birthday, datetime, 'NULL'
6,set nocount {on|off}使返回的結果中不包含有關(guān)受 Transact-SQL 語(yǔ)句影響的行數的信息。如果存儲過(guò)程中包含的一些語(yǔ)句并不返回許多實(shí)際的數據,則該設置由于大量減少了網(wǎng)絡(luò )流量,因此可顯著(zhù)提高性能。SET NOCOUNT 設置是在執行或運行時(shí)設置,而不是在分析時(shí)設置。
SET NOCOUNT 為 ON 時(shí),不返回計數(表示受 Transact-SQL 語(yǔ)句影響的行數)。SET NOCOUNT 為 OFF 時(shí),返回計數
常識
在SQL查詢(xún)中:from后最多可以跟多少張表或視圖:256
在SQL語(yǔ)句中出現Order by,查詢(xún)時(shí),先排序,后取
在SQL中,一個(gè)字段的最大容量是8000,而對于nvarchar(4000),由于nvarchar是Unicode碼。
SQLServer2000同步復制技術(shù)實(shí)現步驟
一、 預備工作
1.發(fā)布服務(wù)器,訂閱服務(wù)器都創(chuàng )建一個(gè)同名的windows用戶(hù),并設置相同的密碼,做為發(fā)布快照文件夾的有效訪(fǎng)問(wèn)用戶(hù)
--管理工具
--計算機管理
--用戶(hù)和組
--右鍵用戶(hù)
--新建用戶(hù)
--建立一個(gè)隸屬于administrator組的登陸windows的用戶(hù)(SynUser)
2.在發(fā)布服務(wù)器上,新建一個(gè)共享目錄,做為發(fā)布的快照文件的存放目錄,操作:
我的電腦--D:\ 新建一個(gè)目錄,名為: PUB--右鍵這個(gè)新建的目錄
--屬性--共享
--選擇"共享該文件夾"
--通過(guò)"權限"按紐來(lái)設置具體的用戶(hù)權限,保證第一步中創(chuàng )建的用戶(hù)(SynUser) 具有對該文件夾的所有權限
--確定
3.設置SQL代理(SQLSERVERAGENT)服務(wù)的啟動(dòng)用戶(hù)(發(fā)布/訂閱服務(wù)器均做此設置)
開(kāi)始--程序--管理工具--服務(wù)--右鍵SQLSERVERAGENT
--屬性--登陸--選擇"此賬戶(hù)"
--輸入或者選擇第一步中創(chuàng )建的windows登錄用戶(hù)名(SynUser)
--"密碼"中輸入該用戶(hù)的密碼
4.設置SQL Server身份驗證模式,解決連接時(shí)的權限問(wèn)題(發(fā)布/訂閱服務(wù)器均做此設置)
企業(yè)管理器--右鍵SQL實(shí)例--屬性
--安全性--身份驗證
--選擇"SQL Server 和 Windows"
--確定
5.在發(fā)布服務(wù)器和訂閱服務(wù)器上互相注冊
企業(yè)管理器--右鍵SQL Server組
--新建SQL Server注冊...
--下一步--可用的服務(wù)器中,輸入你要注冊的遠程服務(wù)器名 --添加
--下一步--連接使用,選擇第二個(gè)"SQL Server身份驗證"
--下一步--輸入用戶(hù)名和密碼(SynUser)
--下一步--選擇SQL Server組,也可以創(chuàng )建一個(gè)新組
--下一步--完成
6.對于只能用IP,不能用計算機名的,為其注冊服務(wù)器別名(此步在實(shí)施中沒(méi)用到)
(在連接端配置,比如,在訂閱服務(wù)器上配置的話(huà),服務(wù)器名稱(chēng)中輸入的是發(fā)布服務(wù)器的IP)
開(kāi)始--程序--Microsoft SQL Server--客戶(hù)端網(wǎng)絡(luò )實(shí)用工具--別名--添加
--網(wǎng)絡(luò )庫選擇"tcp/ip"--服務(wù)器別名輸入SQL服務(wù)器名
--連接參數--服務(wù)器名稱(chēng)中輸入SQL服務(wù)器ip地址
--如果你修改了SQL的端口,取消選擇"動(dòng)態(tài)決定端口",并輸入對應的端口號
二、 正式配置
1、配置發(fā)布服務(wù)器
打開(kāi)企業(yè)管理器,在發(fā)布服務(wù)器(B、C、D)上執行以下步驟:(1)從[工具]下拉菜單的[復制]子菜單中選擇[配置發(fā)布、訂閱服務(wù)器和分發(fā)]出現配置發(fā)布和分發(fā)向導
(2) [下一步] 選擇分發(fā)服務(wù)器 可以選擇把發(fā)布服務(wù)器自己作為分發(fā)服務(wù)器或者其他sql的服務(wù)器(選擇自己)
(3) [下一步] 設置快照文件夾
采用默認\\servername\Pub(4) [下一步] 自定義配置
可以選擇:是,讓我設置分發(fā)數據庫屬性啟用發(fā)布服務(wù)器或設置發(fā)布設置否,使用下列默認設置(推薦)(5) [下一步] 設置分發(fā)數據庫名稱(chēng)和位置 采用默認值
(6) [下一步] 啟用發(fā)布服務(wù)器 選擇作為發(fā)布的服務(wù)器
(7) [下一步] 選擇需要發(fā)布的數據庫和發(fā)布類(lèi)型
(8) [下一步] 選擇注冊訂閱服務(wù)器
(9) [下一步] 完成配置
2、創(chuàng )建出版物
發(fā)布服務(wù)器B、C、D上(1)從[工具]菜單的[復制]子菜單中選擇[創(chuàng )建和管理發(fā)布]命令
(2)選擇要創(chuàng )建出版物的數據庫,然后單擊[創(chuàng )建發(fā)布]
(3)在[創(chuàng )建發(fā)布向導]的提示對話(huà)框中單擊[下一步]系統就會(huì )彈出一個(gè)對話(huà)框。對話(huà)框上的內容是復制的三個(gè)類(lèi)型。我們現在選第一個(gè)也就是默認的快照發(fā)布(其他兩個(gè)大家可以去看看幫助)
(4)單擊[下一步]系統要求指定可以訂閱該發(fā)布的數據庫服務(wù)器類(lèi)型,
SQLSERVER允許在不同的數據庫如 orACLE或ACCESS之間進(jìn)行數據復制。
但是在這里我們選擇運行"SQL SERVER 2000"的數據庫服務(wù)器(5)單擊[下一步]系統就彈出一個(gè)定義文章的對話(huà)框也就是選擇要出版的表
注意: 如果前面選擇了事務(wù)發(fā)布 則再這一步中只能選擇帶有主鍵的表(6)選擇發(fā)布名稱(chēng)和描述
(7)自定義發(fā)布屬性 向導提供的選擇:
是 我將自定義數據篩選,啟用匿名訂閱和或其他自定義屬性否 根據指定方式創(chuàng )建發(fā)布 (建議采用自定義的方式)(8)[下一步] 選擇篩選發(fā)布的方式
(9)[下一步] 可以選擇是否允許匿名訂閱
1)如果選擇署名訂閱,則需要在發(fā)布服務(wù)器上添加訂閱服務(wù)器
方法: [工具]->[復制]->[配置發(fā)布、訂閱服務(wù)器和分發(fā)的屬性]->[訂閱服務(wù)器] 中添加否則在訂閱服務(wù)器上請求訂閱時(shí)會(huì )出現的提示:改發(fā)布不允許匿名訂閱如果仍然需要匿名訂閱則用以下解決辦法 [企業(yè)管理器]->[復制]->[發(fā)布內容]->[屬性]->[訂閱選項] 選擇允許匿名請求訂閱
2)如果選擇匿名訂閱,則配置訂閱服務(wù)器時(shí)不會(huì )出現以上提示
(10)[下一步] 設置快照 代理程序調度
(11)[下一步] 完成配置
當完成出版物的創(chuàng )建后創(chuàng )建出版物的數據庫也就變成了一個(gè)共享數據庫有數據 srv1.庫名..author有字段:id,name,phone,
srv2.庫名..author有字段:id,name,telphone,adress
要求: srv1.庫名..author增加記錄則srv1.庫名..author記錄增加
srv1.庫名..author的phone字段更新,則srv1.庫名..author對應字段telphone更新
--*/ --大致的處理步驟
--1.在 srv1 上創(chuàng )建連接服務(wù)器,以便在 srv1 中操作 srv2,實(shí)現同步
exec sp_addlinkedserver 'srv2','','SQLOLEDB','srv2的sql實(shí)例名或ip'
exec sp_addlinkedsrvlogin 'srv2','false',null,'用戶(hù)名','密碼'
go--2.在 srv1 和 srv2 這兩臺電腦中,啟動(dòng) msdtc(分布式事務(wù)處理服務(wù)),并且設置為自動(dòng)啟動(dòng)
。我的電腦--控制面板--管理工具--服務(wù)--右鍵 Distributed Transaction Coordinator--屬性--啟動(dòng)--并將啟動(dòng)類(lèi)型設置為自動(dòng)啟動(dòng) go --然后創(chuàng )建一個(gè)作業(yè)定時(shí)調用上面的同步處理存儲過(guò)程就行了
企業(yè)管理器 --管理
--SQL Server代理
--右鍵作業(yè)
--新建作業(yè)
--"常規"項中輸入作業(yè)名稱(chēng)
--"步驟"項
--新建
--"步驟名"中輸入步驟名
--"類(lèi)型"中選擇"Transact-SQL 腳本(TSQL)"
--"數據庫"選擇執行命令的數據庫
--"命令"中輸入要執行的語(yǔ)句: exec p_process
--確定
--"調度"項
--新建調度
--"名稱(chēng)"中輸入調度名稱(chēng)
--"調度類(lèi)型"中選擇你的作業(yè)執行安排
--如果選擇"反復出現"
--點(diǎn)"更改"來(lái)設置你的時(shí)間安排
然后將SQL Agent服務(wù)啟動(dòng),并設置為自動(dòng)啟動(dòng),否則你的作業(yè)不會(huì )被執行 設置方法: 我的電腦--控制面板--管理工具--服務(wù)--右鍵 SQLSERVERAGENT--屬性--啟動(dòng)類(lèi)型--選擇"自動(dòng)啟動(dòng)"--確定. --3.實(shí)現同步處理的方法2,定時(shí)同步
--在srv1中創(chuàng )建如下的同步處理存儲過(guò)程
create proc p_process as --更新修改過(guò)的數據
update b set name=i.name,telphone=i.telphone from srv2.庫名.dbo.author b,author i
where b.id=i.id and(b.name <> i.name or b.telphone <> i.telphone) --插入新增的數據
insert srv2.庫名.dbo.author(id,name,telphone)
select id,name,telphone from author i where not exists( select * from srv2.庫名.dbo.author where id=i.id)
--刪除已經(jīng)刪除的數據(如果需要的話(huà))
delete b from srv2.庫名.dbo.author b
where not exists( select * from author where id=b.id)go
1. 要看書(shū)。在成千上萬(wàn)的編程圖書(shū)中,可能很大一部分根本毫無(wú)用處。但是仍然有很多圖書(shū)對你的(編程)能力有很大的提升。我一直堅持,相比在網(wǎng)絡(luò )上查找很多有用信息,在同類(lèi)圖書(shū)中查找要來(lái)得更容易更快捷。閱讀技術(shù)圖書(shū)可心更好地抓住核心內容。對于理論,架構和設計等方面來(lái)說(shuō),圖書(shū)也一樣很有幫助。只不過(guò)要找到高質(zhì)量的、權威的信息,就不如網(wǎng)絡(luò )上可供查找的范圍廣。
2. 讀代碼。這也是我很喜歡的一種方式。如果我并沒(méi)有幾年的專(zhuān)業(yè)編程工作經(jīng)驗,在學(xué)習之初我并不會(huì )去讀很多復雜的代碼。如果我要是早些開(kāi)始學(xué)習,我將是一個(gè)比現在更好的程序員。但是,開(kāi)始時(shí)我會(huì )從一些開(kāi)源項目里,去學(xué)習那些源代碼(當然,這些代碼不能與我的工作有關(guān),也不是我自己寫(xiě)的)。要從自己會(huì )使用到的,或者自己感興趣的程序開(kāi)始這項工作。我是從 Paint.net 這個(gè)網(wǎng)站里開(kāi)始學(xué)習的,而且已經(jīng)積累了很多關(guān)于 .NET 的編程技術(shù)。
讀別人的代碼可以為你提供更多不同的工作思路,這比你完全憑自己思考得到的工作方式要多。
3. 寫(xiě)代碼。謹記,要寫(xiě)大量的代碼。從根本上來(lái)講,最好的學(xué)習方法就是實(shí)踐。如果不寫(xiě)代碼,你根本不能把(某種語(yǔ)言中)內在的東西學(xué)習透徹。學(xué)習之初,可以從一些技術(shù)指南和圖書(shū)中照搬一些盡量簡(jiǎn)單的程序。當然,這種照搬是要自己完全手工輸入,而不是復制和粘貼,這兩種之間的效果差別是很大的。這種方法的主旨就在于,使知識內在化,并思考其用法,而不是盲目照抄。學(xué)習過(guò)程中,要時(shí)常查找新的 API 調用方法,這其實(shí)是簡(jiǎn)單的事情。
最重要的是,要寫(xiě)一個(gè)你自己的程序,不管它是一個(gè)簡(jiǎn)單的游戲,或者是一個(gè)參與開(kāi)源項目的程序,還是一個(gè)公為你自己使用的簡(jiǎn)單插件。用不同的方式來(lái)寫(xiě)程序,盡量嘗試使用新的技術(shù),新的技巧,新的設計方式。一定要讓現在的項目比以往的項目更好。想要成一個(gè)優(yōu)秀的開(kāi)發(fā)者,這一點(diǎn)是核心。
4. 與其他開(kāi)發(fā)者交流。像 Apple,微軟,Google 等大公司一樣的新聞描述的一樣,(與其他開(kāi)發(fā)者交流)可以讓你解決一些復雜的問(wèn)題。雖然這并不能讓你感覺(jué)到自己已經(jīng)成一個(gè)團隊或是社區的成員,但是這種方法可以讓你接觸到更多不同的想法。
不同類(lèi)型的項目要求不同的設計方法,代碼技術(shù),開(kāi)發(fā)流程和設計思想。如果你工作在一個(gè)小團隊里,你不必與太多的人接觸,只要在用戶(hù)群會(huì )議中找到一些人(來(lái)討論)即可。如果這樣還不行的話(huà),參與到在線(xiàn)論壇中與其他人討論(這時(shí)你需要更努力地尋找高質(zhì)量的討論內容)。
6. 教會(huì )別人。相對于僅僅讀代碼之類(lèi)的工作,教其他人學(xué)習可以讓你更深入地學(xué)習某個(gè)技術(shù),這種方法有著(zhù)非凡的效果。教會(huì )別人某個(gè)技術(shù),同樣也會(huì )讓你更專(zhuān)注于這種技術(shù),并且可以比別人更深層次地理解它。同樣你也會(huì )面對一些問(wèn)題。
“如果你不能向一個(gè)六歲的兒童解析清楚一個(gè)概念,那么其實(shí)是你并沒(méi)有完全理解它?!盇lbert Einstein說(shuō)。
教學(xué)場(chǎng)景可以是無(wú)窮無(wú)盡的:與工作搭檔一對一交流,休息碰面,非正式周會(huì ),學(xué)習茶會(huì ),教室,討論發(fā)表會(huì ),等等。每周在相同理念開(kāi)發(fā)者之間舉辦一次30分鐘的非正式會(huì )議怎么樣?每周,讓幾個(gè)人來(lái)就他們想要更深入了解話(huà)題,向大家傳授這些技術(shù)知識,并且展開(kāi)討論。如果你知道你將要向團隊成員們傳授正學(xué)學(xué)習的知識,你是不是更想要了解這項技術(shù)的每個(gè)細節呢?
6. 收聽(tīng)網(wǎng)絡(luò )電臺。如果你有空閑的時(shí)間,可以訂閱網(wǎng)絡(luò )電臺節目。我現在最喜歡的編程節目就是 .Net Rocks。這個(gè)節目還會(huì )做一些視頻節目,叫做 dnrTV 。這樣會(huì )讓你即時(shí)捕捉到最新最好的技術(shù)。一個(gè)人是不能學(xué)習到所有知識的,而網(wǎng)絡(luò )電臺剛是一個(gè)學(xué)習了解廣泛知識的途徑。
7. 閱讀博客。博客遠遠比閱讀者要多,但是其中有一些卻是極其優(yōu)秀的。我這里不并不是要推薦博客,因為網(wǎng)絡(luò )上已經(jīng)有了足夠多的博客。這是與真正在開(kāi)發(fā)你所喜歡和使用的軟件的開(kāi)者聯(lián)系的好方法。
8. 學(xué)習新的語(yǔ)言。即使你已經(jīng)在 C(++,#) / JAVA 等語(yǔ)言上有很好的造詣,仍然有很多其他可以解決問(wèn)題的編程語(yǔ)言。學(xué)習新的語(yǔ)言,是對你已有思維方式的挑戰。這不僅僅是另一種語(yǔ)言,更是對思維的重新架構。的確,所有的語(yǔ)言最后都會(huì )被編譯成匯編程序,但是這并不意味著(zhù)高級語(yǔ)言毫無(wú)價(jià)值。
9. 學(xué)習不正確的方式。除了要學(xué)習應該怎么做,還要學(xué)習不應該怎么做。經(jīng)常閱讀 Dailywtf.com ,學(xué)習你并不知道的經(jīng)驗與教訓。學(xué)習適當的面向對象設計方式,代碼寫(xiě)作方式,和必須要寫(xiě)的代碼等,是很好的方式,但是如果不細心的話(huà)也容易養成不良習慣。學(xué)習認識不正確的思路是負責項目開(kāi)發(fā)至關(guān)重要的一環(huán)。
維基百科對很多覺(jué)的不正確方式有十分透徹的分類(lèi)。
10. 要謙虛。
學(xué)習,意味著(zhù):
只有承認自己有所不足,才能有學(xué)習的動(dòng)力。歸根到底,就是謙虛,不對嗎?如果你開(kāi)始認為你已經(jīng)掌握了所有需要的知識,那么你就危險了。真正的學(xué)習是如饑似渴地追逐知識并使其內在化,這需要很大的努力。我們都知道這一點(diǎn),但是要必須時(shí)常不斷地提醒自己。
聯(lián)系客服