Windows 為什麼要有註冊表而 Unix 就不需要?

註冊表使軟體卸載不幹凈,而 *nix 就沒有註冊表的概念,但包依賴很嚴重。包依賴可以理解為 Windows 的註冊表呢還是 .net 框架?


Windows的可配置項比通常的UNIX發行版多了可能有2個數量級(除了有系統服務的參數、內置應用的參數、各種個人偏好設置,還有數量巨大的組策略選項、COM組件註冊信息)。如果你考慮到這一點,就會發現用文件來配置Windows幾乎不可行

  1. 註冊表實際上是一個層次型資料庫,用來儲存系統和應用的海量配置信息
  2. 做成資料庫可以保證多進程、多線程同時讀寫不出錯
  3. 註冊表有索引,值又是強類型的,所以性能比用文件快,而且佔用資源小。這在Windows早期是很重要的特性
  4. 做成資料庫還可以支持視圖:比如,HKEY_CURRENT_USER,方便應用編程
  5. 軟體卸載不幹凈是反安裝程序沒寫好,和註冊表無關。同理,反安裝程序忘刪文件的話,也不能怪文件系統不好
  6. 包依賴是另外一個問題,建議新開

第一個問題大家答的很好了,我來試試第二個問題。
===========================
第二個問題要從linux發行版和windows不同的軟體安裝方式說起了。

下面簡單的將軟體分為主程序和依賴庫。主程序是這個軟體獨一無二的程序,而依賴庫是可以與其他軟體共享的程序,例如C運行庫。

Linux:Linux發行版的提供廠商都會維護一個軟體倉庫(software repository),軟體倉庫中軟體都是經過廠商測試並且已經解決好依賴關係的。在linux下安裝軟體,其實就是通過廠商提供的包管理工具(debian系的apt-get,redhat系的yum)去和廠商的軟體倉庫同步。這樣,linux的軟體世界實際上是一個集中式的體系結構,有一個統一而且負責的維護者。因此,在軟體倉庫中,軟體的主程序和依賴庫是可以完全的分開為不同的包(package)的,因為維護良好的依賴關係可以保證自動化得找到並安裝所有的依賴庫。下圖是在Ubuntu安裝gcc

第一個紅框內是安裝命令,第二個是找到的依賴庫(依賴包),第三個是為了安裝gcc這個軟體實際下載並安裝了那些包。Windows:windows下的軟體開發者都是各干各的,沒有人去維護什麼軟體倉庫什麼依賴關係。如果軟體依賴某個 dll 怎麼辦呢?windows程序員使用了一個很簡單的方法,我把主程序和依賴庫打包為一個文件整體發布不就行了!!!這樣自然也就不會存在什麼依賴關係了。
下圖是在Program Files下搜索msvcr80.dll這個常見的庫文件,我們可以看到windows程序員為了解決依賴問題帶來了多少冗餘的msvcr(這個其實就是C語言運行庫)

所以說,Windows並不是沒有依賴關係,只是Windows程序員在發布程序的時候把依賴的庫和主程序一塊發布給了用戶。


誰說UNIX不需要呀,只是UNIX沒有一個有統治力的系統配置資料庫實現罷了。

當然,放在 UNIX 出現的年代,「一切皆是文本」的概念確實是革命性的,偉大的進步,極具美感和優雅。現在的計算機規模已經不是當年的那個量級了,單機內的系統複雜度也遠勝當年。DLL地獄什麼的,*nix 一樣有。卸載和安裝問題,如果自己瞎搞,在 UNIX/LINUX 下面也一樣會發生。我印象特別深的就是當年手賤,自己make了一個perl.deb,安裝完又用apt刪掉了……

不說了,我想靜靜……

你說的那些問題其實更多的是安裝程序的製造者的問題,而不是系統問題,在哪個系統里都有,我現在就在折騰 postgresql9.4 的 debian docker,debian testing下是beta3,pg官方源是rc1,一樣搞不定。


首先啊,Windows也有不用註冊表的方式配置,也就是ini方式的配置,至於為什麼windows有註冊表這麼個東西呢,因為windows就像一個全能的貼身管家,它會負責幫您處理好您電腦上的幾乎所有的實務,要知道電腦裡面的事非常多,如果才能高效的處理好,註冊表就發揮了好大的一個作用了;而相對的,Unix,它則是「我只負責這個功能,其他的關我屁事」(當然基於配置文件也跟它一切皆文件的思想有關了)。
至於題主說的卸載不幹凈,那就不是註冊表的事情了,就跟你家裡大掃除只掃地不擦窗一個道理,而同樣的,Unix中也經常發生卸載不幹凈的形況,每個人習慣不同,有的人會把軟體裝"/usr/local"用的人裝「/usr/」也有人裝「/opt」或者其他,各種bin、etc、include或者會扔到到處都是,這個時候讓你來卸載,或許你會直接把它重裝一了百了。


註冊表,是微軟的做法:把所有配置都存在一個地方(樹形資料庫);
*nix的做法是:每個應用自己有一套小的配置文件。

各有優劣:
前者統一存儲,找起來方便,不容易遺漏,但是壞了後果嚴重(危及整個系統),想複製一個應用的配置,比較麻煩(有些應用的配置不僅僅是在一個分支里的);
後者各自配置,分散、凌亂,但壞了隻影響自己(一個應用),複製一個應用的配置比較方便。

總的來說,還是*nix的做法更好一些。
因為備份所有配置的機會不多,恢復到別的電腦,意義不大。
複製個別應用的配置到另一台電腦的機會比較多。

win下的應用,直接使用配置文件也可以的,註冊表出現前,就是都使用ini的。
我寫的win下的應用,也是都使用ini的,盡量不註冊表(除非是需要操作系統自動做什麼)
這樣的程序才綠色(即拷即用,即刪即清)

---補充包依賴部分,在另一個問題里回答過:
為什麼Linux上的軟體不需要「安裝」 為什麼很多軟體不做成「綠色軟體」?

另外:win下的程序有些卸載不徹底,是因為 有些配置信息可能是人為設置的結果,程序卸載了而它們仍保留配置,是方便用戶在下次安裝後無須再人為重新設置,直接就是利用上次設置的效果了


其實這兩者的區別就是文件和資料庫的區別。

文件是自由地排列在硬碟上的,可以是任意的二進位組合。資料庫則是一個大集合,裡面的數據類型相對來說是固定的,且有專門針對資料庫優化的讀寫演算法,方便管理。你可以打開 Windows 的註冊表編輯器,看看裡面放了多少內容。其實那裡面的內容,微軟自身組件(包括自帶的和後來安裝的 Office, VS 等)的配置佔了絕大多數,其他第三方軟體所佔的數量真的不多。

文件在處理小數據時有優勢,而資料庫在處理大數據時有優勢,因為資料庫能指定數據類型,節省空間且能加快處理速度。舉個例子好了,我們有這樣一個 ini 文件:

[Config]
InstallPath=C:SoftMediaPlayer
InstallDate=2016.08.26
InstallTime=13:00:00
LastUsedTimeStamp=1472187840
LastPlayedMedia=D:Moviesドラえもんー劇場版2016.mkv
UsedCount=1

那麼,當我們讀取這個 ini 文件的時候,我們首先要在程序中將這五個配置項的數據從原先清一色的字元串類型轉換成相應的數據類型(第一項字元串,第二項日期,第三項時間,第四項和第五項都是整型),這無形中增加了時間消耗,且如果手動修改過該文件,則容易出現溢出、類型無法轉換等問題。資料庫里由於可以限定數據類型,使得溢出、轉換失敗這類問題不復存在。

另外,資料庫由於是統一管理,所以有很多安全特性是散漫的文件所做不到或很難做到的,比如備份、操作日誌、許可權等。這些因為我沒有學習過相關專業知識,也不在從事這方面的工作,就不獻醜了。

Linux 是自由軟體,它本身只是一個內核,我們安裝的很多 Linux 發行版其實是預裝了很多第三方軟體的,比如 Gnome 桌面等,其實它並不是 Linux 內核的一部分,我們在用的所有 Linux 軟體其實都是第三方軟體,那麼作為內核,就沒有必要再像 Windows 那樣提供一個統一的資料庫管理入口了,各個軟體自己規劃數據管理方式。Windows 的註冊表裡不也都是微軟家的信息么?雖然這不見得就是正確的,但大家既然都認可了這種管理方式,那就這樣吧。

至於包依賴,其實 Windows 也有,只不過沒那麼顯眼罷了。你可以到控制面板的【添加刪除程序】里看看有多少個叫做【Microsoft Visual C++ Redistributable】的程序。通常情況下,每種年份的各保留一個 x86 和 x64 架構的就行了,因為 Windows 沒有提供一種成熟的包管理機制,所以很多軟體都為了保險起見,在安裝程序時順帶把需要依賴的 C++ 運行庫裝上了,但各家用的版本又有微小的差異,比如 9.0.30729.4148 和 9.0.30729.6161,這兩個運行庫大版本號一樣,後者相當於前者的升級補丁,理論上只需要後者就行了,但因為各種安裝程序都自帶了 C++ 運行庫,再加上版本有這種微小的差異,所以我們就看到了 N 多的運行庫。當然,除了控制面板里的,還有更多,不信你全盤搜索 msvcr*.dll,看看能搜到多少冗餘?這也沒辦法,因為 Windows 沒有包管理機制,所以安裝程序本身無法判斷自己所依賴的庫是否存在,到時候裝上了系統又提示找不到哪個哪個 dll,用戶反過來還要怪開發者。

Linux 其實也可以不依賴包管理,所有軟體都用源碼編譯,追根溯源把所有的依賴項按順序編譯好也不是不可以。但這裡有個問題,Linux 下的很多軟體都是開源軟體,而在開源軟體社區有很多做框架的,五花八門的,很多程序員直接以一些開源框架為基準拼出了一個程序。可關鍵是這些框架有共性嗎?是不是絕大多數的程序都得用 numpy?Windows 下真正的依賴項其實沒那麼多,很多都是用 Windows 自帶的 API 來完成的,頂多加個 C++ 運行庫,以及 .net 什麼的。而開源社區,一個開源程序可能依賴了 N 多項,甚至是層層遞進的,比如 OpenCV 依賴於 avcodec, ffmpeg, gstreamer, gtk, libjpeg, libpng 這些多媒體框架,以及設計計算的矩陣框架 numpy 等。而用於深度學習的 BVLC Caffe 依賴於 OpenCV,以及 protobuf, lmdb 這些數學庫。這些庫你可能在 Windows 上都沒聽說過。正因為開源社區的錯綜複雜,所以才有必要提供一個包管理的機制,提高親和度。Windows 下沒必要,即使用到了一些非主流的框架,直接包含在程序目錄中即可,不需要費大工夫弄一套包管理機制,畢竟這是有成本的,微軟自己就是做軟體的,沒那個心思去維護別人的軟體。

最後,包管理和註冊表沒有直接關聯,這是底層上的區別,不是數據管理這種應用層面上的區別。


@李遙 對註冊表出現的需求解釋的很到位,但是,註冊表最終還是作為二進位資料庫保留下來,說明了 Windows 和 Unix 對待「performance hack」的不同態度。Windows 的態度是:當年我需要,後來要兼容,就這樣了。Unix 的態度就是慢慢從底層優化、替代,淘汰舊的機制,保留策略的可選擇性。

卸載不能完全清除配置信息,是大型軟體固有的問題。Unix 也不能說完全解決。

包依賴是某些 Unix,特別是某些 Linux 發行版,對冗餘的過分潔癖。Redundency is bad, dependency is worse。


誰說Unix就沒有註冊表了?
比如GNOME就有,只是不叫註冊表:

至於為什麼很多軟體沒有用類似這種的機制,只是因為配置選項比較少而已。
對於GNOME這種大傢伙來說,用類似註冊表的樹狀結構資料庫會方便得多。


怎麼沒有人提到:
1、COM組件,用註冊表查詢介面與實現的對應多快啊,還可以延遲載入;
2、安全性,註冊表可以定義非常細緻的安全訪問級別,而配置文件只能依賴文件的安全性了;
其實微軟近幾年也弱化了註冊表,你看開源的.net都直接json作為配置文件了。


不是註冊表使軟體卸載不幹凈,而是開發者沒寫好(有些是故意的)軟體卸載程序


我先假設題主說的是unix是unix-like包含linux等把。因為閉源的unix我實在是沒用過,也沒有發言權。

1. 註冊表和linux系的/etc基本是差不多的作用,都是用來存儲系統及軟體設置的地方。 至於存些什麼, 都是由應用軟體自己決定的。 區別就是,一個是資料庫, 一個是目錄樹。實質上並沒有什麼不同。 這是設計決策的問題。 linux偏愛文件系統, 所以就用了文件系統而已。題主所說的卸載不幹凈並不是註冊錶帶來的問題, 而是各種軟體的installer腳本寫得不夠好的問題。 在linux下安裝和卸載蹩腳的軟體, 同樣也會有殘留。

2.包依賴的問題這在各個平台下都有。 只不過誰做的早,誰做的晚。windows的manifest也是為了這個解決這個問題而生的。 xp之前就是一團漿糊。

windows因為是大而全,由一家開發,發行周期長,更新慢,內容多,也不需要管理include和src,所以系統本身提供的類庫依賴性天生就不需要用戶擔心(第三方類庫依然是漿糊)

而linux系是由無數多的個人和小團體開發,慢慢被修改完善的,每個工具和庫都有無數的版本, 也都有自己以來的不同版本的包,再加上需要管理include和src,顯得比較混亂。但事實上,並沒有哪個Linux軟體會因為包版本問題而跑不起來。也就是說, 都是可以解決的。所以我認為, linux系的包管理已經足夠好了。對初級用戶來說,可以自動的在repo中解決大部分的依賴問題. 這一點, windows顯然是做不到的把?


註冊表跟普通文件最大的區別就是,他是transactional的,就算你硬碟寫了一半斷電了,註冊表本身的格式也不會被破壞。你自己把配置維護在自己的文件裡面,一不小心寫掛了,就完了吧,你真的回去這麼認真的做災難恢復嘛,顯然是不會的。


至於為什麼註冊表顯得有點不好,這完全是因為windows自帶了regedit,要是從一開始你就只能用api訪問,那也沒那麼多菜鳥會去亂動然後怪windows的註冊表了。


Windows是選擇了用註冊表,而不是它註定要用註冊表。
Unix有自己的哲學,TA希望數據文件都是文本化的,這樣程序間才可以互操作,而不用費力去解析二進位文件。比如說搜索Unix內某用戶的信息,可以用任何一種編輯器,vim,sed,emacs,甚至grep,cat,less等等。要查看某進程的堆棧,同樣是用這些工具。
但是用Windows的註冊表的話,一般你只能使用【註冊表編輯器】或【用戶】等專用的程序來察看。
當然,註冊表有自己的優點,我可以理解的優點就是速度快。因為是二進位嘛~

包依賴可以理解為,額,.net里的dll?你寫.net程序時會注意到這個的。
但是Unix里的包不僅僅是鏈接庫,是bin,lib,include,doc等等的打包。


中央集權和聯邦制的區別。


Windows多用戶系統及使用時,註冊表使得各用戶配置能相對獨立,同時共用運行資源變得簡單。

而Linux編譯或安裝文件時,運行、配置文件就像老母雞下蛋一樣,扔得到處都是。


為什麼linux /etc下那麼多文件而windows沒有那麼多?


WINDOWS和類UNIX系統的設計哲學不一樣。WINDOWS不是微內核的,OS要全包全管,肯定有個統一存放配置信息的地方比較合理;UNIX是微內核的,內核之外全是「工具」, 所以/etc下一堆東西。工具們自己管好自己的事情,工具之間通過管道交互即可。


win,因為當初win的幾乎每個配置都要應用自己去檢索和修改內容,這就需要每個應用都要自己實現讀寫配置的代碼;且在win軟體大量增加以後,各應用間共享配置的要求日益增多,所以就有了註冊表。
unix有/etc目錄樹,因為*nix系列,有shell腳本,有n個工具,n*m個方法來檢索和修改/etc中配置中的文本,所以一般沒必要自己實現代碼做這個,各應用配置內容格式雖然五花八門可存儲格式一般都是txt。
不過linux的gnome就早已有了類似註冊表的東西……


*nix有/etc呀,而且這個目錄有時候軟體卸載以後也不一定會清理乾淨


其實通用操作系統原理都一樣 只是表現形式不一樣。unix有smit Linux有yast windows有控制面板 相應的都會有註冊信息管理安裝的軟體(廣義上的)


推薦閱讀:

UNIX 文化中有哪些元素?

TAG:MicrosoftWindows | Unix | .NET | 註冊表 |