连接pgsql_Laravel 数据库连接配置和读写分离
今天開始講如何在 Laravel 中操作數據庫,Laravel 為我們提供了多種工具實現對數據庫的增刪改查,在我們使用 Laravel 提供的這些數據庫工具之前,首先要連接到數據庫。
數據庫的連接配置文件位于 config/database.php,和很多其他 Laravel 配置一樣,你可以為數據庫配置多個「連接」,然后決定將哪個「連接」作為默認連接。
基本配置
默認情況下,Laravel 為支持的每一種數據庫定義了一個連接配置項:
'connections'?=>?[????'sqlite'?=>?[
????????'driver'?=>?'sqlite',
????????'database'?=>?env('DB_DATABASE',?database_path('database.sqlite')),
????????'prefix'?=>?'',
????],
????'mysql'?=>?[
????????'driver'?=>?'mysql',
????????'host'?=>?env('DB_HOST',?'127.0.0.1'),
????????'port'?=>?env('DB_PORT',?'3306'),
????????'database'?=>?env('DB_DATABASE',?'forge'),
????????'username'?=>?env('DB_USERNAME',?'forge'),
????????'password'?=>?env('DB_PASSWORD',?''),
????????'unix_socket'?=>?env('DB_SOCKET',?''),
????????'charset'?=>?'utf8mb4',
????????'collation'?=>?'utf8mb4_unicode_ci',
????????'prefix'?=>?'',
????????'strict'?=>?true,
????????'engine'?=>?null,
????],
????'pgsql'?=>?[
????????'driver'?=>?'pgsql',
????????'host'?=>?env('DB_HOST',?'127.0.0.1'),
????????'port'?=>?env('DB_PORT',?'5432'),
????????'database'?=>?env('DB_DATABASE',?'forge'),
????????'username'?=>?env('DB_USERNAME',?'forge'),
????????'password'?=>?env('DB_PASSWORD',?''),
????????'charset'?=>?'utf8',
????????'prefix'?=>?'',
????????'schema'?=>?'public',
????????'sslmode'?=>?'prefer',
????],
????'sqlsrv'?=>?[
????????'driver'?=>?'sqlsrv',
????????'host'?=>?env('DB_HOST',?'localhost'),
????????'port'?=>?env('DB_PORT',?'1433'),
????????'database'?=>?env('DB_DATABASE',?'forge'),
????????'username'?=>?env('DB_USERNAME',?'forge'),
????????'password'?=>?env('DB_PASSWORD',?''),
????????'charset'?=>?'utf8',
????????'prefix'?=>?'',
????],
],
包括 SQLite、MySQL、PostgresSQL、SQL Server,一般我們默認使用的都是 MySQL:
'default'?=>?env('DB_CONNECTION',?'mysql'),當然,默認數據庫連接、數據庫名稱以及數據庫用戶名和密碼等敏感信息都保存到 .env 文件中了,然后通過 env 輔助函數讀取:
DB_CONNECTION=mysqlDB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
我們平時修改數據庫連接信息的話修改這里就好了,默認配置值是針對 Homestead 開發環境配置的,如果你使用的是 Homestead 作為開發環境的話,開箱即用,不用做任何修改,如果不是的話則需要根據自己的環境做修改,比如學院君使用的是 Laradock,配置信息如下(數據庫名稱、用戶名、密碼以自己的環境為準,不要照搬):
DB_CONNECTION=mysqlDB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel57
DB_USERNAME=root
DB_PASSWORD=root
做好以上配置后,你就可以在 Laravel 項目中連接上 MySQL 數據庫了。
配置多個數據庫連接
有時候,我們的應用用到的不止一個數據庫,或者做項目遷移的時候要做新老數據庫之間的數據遷移,這個時候我們就可以配置多個數據庫連接,如果我們的新老數據庫使用的都是 MySQL 的話,可以在 config/database.php 的 connections 配置項中新增一個 MySQL 連接:
'mysql_old'?=>?[????'driver'?=>?'mysql',
????'host'?=>?env('DB_HOST_OLD',?'127.0.0.1'),
????'port'?=>?env('DB_PORT_OLD',?'3306'),
????'database'?=>?env('DB_DATABASE_OLD',?'forge'),
????'username'?=>?env('DB_USERNAME_OLD',?'forge'),
????'password'?=>?env('DB_PASSWORD_OLD',?''),
????'unix_socket'?=>?env('DB_SOCKET_OLD',?''),
????'charset'?=>?'utf8mb4',
????'collation'?=>?'utf8mb4_unicode_ci',
????'prefix'?=>?'',
????'strict'?=>?true,
????'engine'?=>?null,
],
然后在 .env 中新增對應配置項:
DB_CONNECTION_OLD=mysqlDB_HOST_OLD=mysql
DB_PORT_OLD=3306
DB_DATABASE_OLD=laravel56
DB_USERNAME_OLD=root
DB_PASSWORD_OLD=root
接下來,我們要怎樣連上這個實例呢?默認情況下,我們在通過 Laravel 提供的數據庫工具(DB 門面、查詢構建器、Eloquent模型)連接數據庫的時候,都沒有顯式指定連接,因為我們在配置文件中指定了默認的連接 mysql。所以要連接上其它連接很簡單,在查詢的時候指定這個新的連接就好了,如果你使用的是 DB 門面執行原生 SQL 查詢,可以這么連接老的數據庫:
$users?=?DB::connection('mysql_old')->select(...);DB::connection('mysql_old')->insert(...);
如果你使用的是查詢構建器進行數據庫操作,可以這么指定(和原生操作一樣):
$users?=?DB::connection('mysql_old')->table('users')->where(...)->get();DB::connection('mysql_old')->table('users')->insert(...);
如果你使用的 Eloquent 模型類,可以在對應模型類中設置 $connection 屬性:
protected?$connection?=?'mysql_old';這樣,在模型類上執行查詢、插入等操作時都會使用這個 mysql_old 數據庫連接。
配置數據庫讀寫分離連接
理論上來說,配置數據庫讀寫分離連接也屬于配置多個數據庫連接的范疇,但是由于是一個比較特殊又很常見的使用場景,所以我們單獨來討論,Laravel 也對此進行了單獨支持。
隨著應用訪問量的增長,對數據庫進行讀寫分離可以有效的提升應用整體性能,關于數據庫層面的讀寫分離配置不屬于本教程討論范疇,我們這里只討論從應用層面如何在 Laravel 項目中配置讀寫分離連接。Laravel 框架數據庫底層代碼對數據庫讀寫分離進行了支持,所以我們需要遵循底層實現進行讀寫分離配置:
'mysql'?=>?[????'driver'?=>?'mysql',
????'read'?=>?[
????????'host'?=>?env('DB_HOST_READ',?'127.0.0.1'),
????],
????'write'?=>?[
????????'host'?=>?env('DB_HOST_WRITE',?'127.0.0.1')
????],
????'port'?=>?env('DB_PORT',?'3306'),
????'database'?=>?env('DB_DATABASE',?'forge'),
????'username'?=>?env('DB_USERNAME',?'forge'),
????'password'?=>?env('DB_PASSWORD',?''),
????'unix_socket'?=>?env('DB_SOCKET',?''),
????'charset'?=>?'utf8mb4',
????'collation'?=>?'utf8mb4_unicode_ci',
????'prefix'?=>?'',
????'strict'?=>?true,
????'engine'?=>?null,
],
read 項配置的是「讀」連接,write 項配置的是「寫」連接。然后在 .env 中新增 DB_HOST_READ 和 DB_HOST_WRITE 配置項。當然,對于 Web 應用而言,大多是讀多寫少,所以你還可以配置多個 read 主機,Laravel 底層的負載均衡機制是隨機從配置的 IP 中挑一個連接:
'read'?=>?[????'host'?=>?[env('DB_HOST_READ_1'),?env('DB_HOST_READ_2')],
],
有的人會問,如果我們讀寫數據庫的用戶名、密碼不一樣咋辦?好辦,上面這種配置默認讀寫連接使用的用戶名密碼一樣,那我們在讀寫配置項中分別獨立配置就好了:
'mysql'?=>?[????'driver'?=>?'mysql',
????'read'?=>?[
????????'host'?=>?env('DB_HOST_READ',?'127.0.0.1'),
????????'username'?=>?env('DB_USERNAME_READ',?'forge'),
????????'password'?=>?env('DB_PASSWORD_READ',?''),
????],
????'write'?=>?[
????????'host'?=>?env('DB_HOST_WRITE',?'127.0.0.1'),
????????'username'?=>?env('DB_USERNAME_WRITE',?'forge'),
????????'password'?=>?env('DB_PASSWORD_WRITE',?''),
????],
????'port'?=>?env('DB_PORT',?'3306'),
????'database'?=>?env('DB_DATABASE',?'forge'),
????'unix_socket'?=>?env('DB_SOCKET',?''),
????'charset'?=>?'utf8mb4',
????'collation'?=>?'utf8mb4_unicode_ci',
????'prefix'?=>?'',
????'strict'?=>?true,
????'engine'?=>?null,
],
其他公共配置項也是同理,不再贅述。
針對讀寫分離數據庫的連接,Laravel 數據庫底層會自動判斷,如果是查詢語句會使用讀連接,如果是數據庫插入、更新、刪除等操作會使用寫連接。
讀寫分離本地模擬測試
我們可以在本地簡單模擬測試下讀寫分離配置,我們使用同一個數據庫主機,不同的數據庫來進行讀寫分離,在數據庫中創建一個新的數據庫用作寫數據庫,并將其配置到 config/database.php:
'mysql'?=>?[???'driver'?=>?'mysql',
???'read'?=>?[
???????'host'?=>?env('DB_HOST_READ',?'127.0.0.1'),
???????'database'?=>?env('DB_DATABASE',?'db_read'),
???],
???'write'?=>?[
???????'host'?=>?env('DB_HOST_WRITE',?'127.0.0.1'),
???????'database'?=>?env('DB_DATABASE_WRITE',?'db_write'),
???],
???'port'?=>?env('DB_PORT',?'3306'),
???'username'?=>?env('DB_USERNAME',?'root'),
???'password'?=>?env('DB_PASSWORD',?''),
???'unix_socket'?=>?env('DB_SOCKET',?''),
???'charset'?=>?'utf8mb4',
???'collation'?=>?'utf8mb4_unicode_ci',
???'prefix'?=>?'',
???'strict'?=>?true,
???'engine'?=>?null,
],
然后我們在命令行運行 php artisan migrate,就會將數據庫遷移應用到寫數據庫,因為數據庫更新也屬于寫操作,所以此時自動判讀使用寫連接。
然后我們通過 Tinker 插入一條記錄(插入屬于寫操作,自動使用寫連接):
然后你會在寫數據庫中看到這條記錄,讀數據庫中沒有,接下來,我們運行一條查詢語句(查詢屬于讀操作,自動使用讀連接):
此時,由于我們并沒有配置讀寫數據庫之間的數據同步,所以只能查出來我們在上一篇教程中在讀數據庫中插入的記錄。所以在 Laravel 中實現讀寫分離還是很方便的,我們只需要做好配置就好了,剩下的框架幫我們完成。
當然,和多個數據庫連接類似,你也可以在使用時顯式進行指定,以查詢構建器為例:
DB::connection('read')->table('users')->where(...)->get();DB::connection('write')->table('users')->insert(...);
如果通過 Eloquent 模型類調用的話,還可以這么指定:
User::on('read')->where(...)->get();User::onWriteConnection()->save();
注:關于數據庫的各種增刪改查操作,后面會一一介紹。
讀寫分離配置中的 `sticky` 配置項
在讀寫分離配置中,我們注意到新增了一個 sticky 配置項,這個是用來干嘛的呢?
我們配置數據庫讀寫分離的時候,會配置讀數據庫(從庫)從寫數據庫(主庫)同步數據,由于不同主機之間數據同步是需要時間的,雖然這個時間很短,但是對于并發量很大的應用,還是可能出現寫入寫數據庫的數據不能立即從讀數據庫讀取到的情況,sticky 配置項在這個時候就派上用場了。如果該配置項設置為 true 的話,在同一個請求生命周期中,寫入的數據會被立刻讀取到,底層原理其實就是讀操作也從寫數據庫讀取,因為寫數據庫始終是最新數據,從而避免主從同步延遲導致的數據不一致。
其它配置項
除了上面提到的數據庫連接配置外,config/database.php 配置文件中還有一些其它配置項,你可以通過 migrations 配置項自定義數據庫遷移表的名稱,默認是 migrations:
'migrations'?=>?'migrations',還可以通過 redis 配置項配置 Redis 作為 NoSQL 數據庫的連接配置:
'redis'?=>?[????'client'?=>?'predis',
????'default'?=>?[
????????'host'?=>?env('REDIS_HOST',?'127.0.0.1'),
????????'password'?=>?env('REDIS_PASSWORD',?null),
????????'port'?=>?env('REDIS_PORT',?6379),
????????'database'?=>?env('REDIS_DB',?0),
????],
????'cache'?=>?[
????????'host'?=>?env('REDIS_HOST',?'127.0.0.1'),
????????'password'?=>?env('REDIS_PASSWORD',?null),
????????'port'?=>?env('REDIS_PORT',?6379),
????????'database'?=>?env('REDIS_CACHE_DB',?1),
????],
],
你可以看到 Redis 也支持多個連接,一個默認連接和一個用作緩存的 cache 連接。這一思想在 Laravel 配置中無處不在,很多服務都支持配置多個連接提供不同的驅動,比如 Session 支持文件、數據表等連接,緩存支持 Memcached、Redis 等連接,隊列支持數據庫、Beanstalkd 等連接。你可以為它們定義多個連接,然后指定一個默認連接,這樣做的好處是,當某個連接出現問題,或者你想切換到其它實現,只需動動手指頭修改下配置文件中的默認配置項就好了,極大的提高了系統的可維護性。
注:關于 Redis 我們會在后面單獨講,這里不做深入討論。
本系列教程首發在學院君網站(xueyuanjun.com),你可以點擊頁面左下角閱讀原文鏈接查看最新更新的教程。
總結
以上是生活随笔為你收集整理的连接pgsql_Laravel 数据库连接配置和读写分离的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 信息学奥赛一本通 1312:【例3.4】
 - 下一篇: 信息学奥赛一本通 1195:判断整除 |