mysql5.7の生成列の皆さんは本当に理解していません


MySQL 5.7では、カラムを生成するという新しい機能が導入されました.このカラムのデータは、定義済みの式に基づいて計算されるか、他のカラムから計算されるため、生成カラムと呼ばれます.くだらないことは言わないで、まず時計の構造を見てみましょう.
CREATE TABLE IF NOT EXISTS contacts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

この時計には姓と名前とemailが保存されています.もし私たちがこの人のフルネームを取得するには、次のようにします.
SELECT 
    id, CONCAT(first_name, ' ', last_name), email
FROM
    contacts;

これは最適なクエリーではないことは明らかですが、MySQLで生成されたカラムを使用すると、次のようにcontactsテーブルを再作成できます.
DROP TABLE IF EXISTS contacts;

CREATE TABLE contacts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    fullname varchar(101) GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)),
    email VARCHAR(100) NOT NULL
);

上記のGENERATED ALWAYS as(expression)は、生成カラムを作成する構文です.テストする場合は、いくつかのデータを挿入してテストすることができます.ここでは余計なことは言わないでください.しかし、mysqlは、ストレージと仮想の2つのタイプの生成カラムを提供していることを知っておく必要があります.データを読み込むたびに、仮想カラムは実行中に計算され、格納されたカラムはデータ更新時に物理的に計算され、格納されます.ここから見ると、私たちが定義したのは仮想列ですよ.皆さん、決して混同しないでください.
生成カラムを定義する構文を具体的に見てみましょう.
column_name data_type [GENERATED ALWAYS] AS (expression)
   [VIRTUAL | STORED] [UNIQUE [KEY]]

最初のcolumn_nameとdata_typeはもちろん、カラム名とそのデータ型を指定します.完了後のGENERATED ALWAYS句は,現在の列が生成された列であることを示す.完了したら、対応するオプションを使用して、生成カラムのタイプを示す:VIRTUALまたはSTORED.デフォルトでは、生成カラムのタイプが明確に指定されていない場合、mysqlはVIRTUALを使用します.その後、ASキーワードの後ろにあるカッコ内で式を指定します.この式には、文字、組み込み関数、パラメータなし、オペレータ、または同じテーブル内の任意のカラムへの参照が含まれます.関数を使用する場合は、スカラーと確定性が必要です.最後に、生成されたカラムが格納されている場合は、一意の制約を定義できます.では、実例を見てみましょう.まず、次の表の構造を見てみましょう.
mysql> desc products;
+--------------------+---------------+------+-----+---------+-------+
| Field              | Type          | Null | Key | Default | Extra |
+--------------------+---------------+------+-----+---------+-------+
| productCode        | varchar(15)   | NO   | PRI |         |       |
| productName        | varchar(70)   | NO   |     | NULL    |       |
| productLine        | varchar(50)   | NO   | MUL | NULL    |       |
| productScale       | varchar(10)   | NO   |     | NULL    |       |
| productVendor      | varchar(50)   | NO   |     | NULL    |       |
| productDescription | text          | NO   |     | NULL    |       |
| quantityInStock    | smallint(6)   | NO   |     | NULL    |       |
| buyPrice           | decimal(10,2) | NO   |     | NULL    |       |
| MSRP               | decimal(10,2) | NO   |     | NULL    |       |
+--------------------+---------------+------+-----+---------+-------+
9 rows in set

では、quantityInStockbuyPriceのデータを使用して、SKUの株価を次の式で計算します.
quantityInStock * buyPrice

これは通常sku値を取得する方法ですが、以下のalert tableを使用することができます.add column文は、stock_valueという名前のストレージの生成列をproductsテーブルに追加し、次の文を参照してください.
ALTER TABLE products
ADD COLUMN stockValue DOUBLE 
GENERATED ALWAYS AS (buyprice*quantityinstock) STORED;

通常、ALTER TABLE文は完全なテーブル再構築を必要とするため、大きなテーブルを変更するのに時間がかかります.ただし、仮想カラムはそうではありません.ここで、products表から直接在庫値を問い合わせることができます.sqlを見てみましょう.
SELECT 
    productName, ROUND(stockValue, 2) AS stock_value
FROM
    products;

上記のクエリ文を実行すると、次の結果が得られます.
+---------------------------------------------+-------------+
| productName                                 | stock_value |
+---------------------------------------------+-------------+
| 1969 Harley Davidson Ultimate Chopper       |   387209.73 |
| 1952 Alpine Renault 1300                    |   720126.90 |
| 1996 Moto Guzzi 1100i                       |   457058.75 |
| 2003 Harley-Davidson Eagle Drag Bike        |   508073.64 |
| 1972 Alfa Romeo GTA                         |   278631.36 |
| 1962 LanciaA Delta 16V                      |   702325.22 |
| 1968 Ford Mustang                           |     6483.12 |
|**************    many many   ****************************|
| The Queen Mary                              |   272869.44 |
| American Airlines: MD-11S                   |   319901.40 |
| Boeing X-32A JSF                            |   159163.89 |
| Pont Yacht                                  |    13786.20 |
+---------------------------------------------+-------------+
110 rows in set

はい、今回の記録はここまでです.いい感じだったら、応援よろしくね..