mirror of
https://github.com/Estom/notes.git
synced 2026-04-05 11:57:37 +08:00
数据流水线技术
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -78,6 +78,5 @@
|
||||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xutility": "cpp"
|
||||
},
|
||||
"python.pythonPath": "D:\\anaconda\\envs\\ml\\python.exe"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
## 概述
|
||||
|
||||
### 概念
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8-final"
|
||||
},
|
||||
"orig_nbformat": 2,
|
||||
"kernelspec": {
|
||||
"name": "python388jvsc74a57bd05ef0042cb263260037aa2928643ae94e240dd3afaec7872ebebe4f07619ddd0c",
|
||||
"display_name": "Python 3.8.8 64-bit ('ml': conda)"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Downloading data from https://storage.googleapis.com/tff-datasets-public/fed_emnist_digitsonly.tar.bz2\n",
|
||||
"97402880/97398400 [==============================] - 6s 0us/step\n",
|
||||
"WARNING:tensorflow:AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F610DF820> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n",
|
||||
"WARNING: AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F610DF820> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n",
|
||||
"WARNING:tensorflow:AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F610DD940> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n",
|
||||
"WARNING: AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F610DD940> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n",
|
||||
"WARNING:tensorflow:AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F6231CB80> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n",
|
||||
"WARNING: AutoGraph could not transform <function client_data.<locals>.<lambda> at 0x0000016F6231CB80> and will run it as-is.\n",
|
||||
"Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\n",
|
||||
"Cause: module 'gast' has no attribute 'Index'\n",
|
||||
"To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "error",
|
||||
"ename": "TypeError",
|
||||
"evalue": "from_keras_model() got an unexpected keyword argument 'dummy_batch'",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[1;32m<ipython-input-2-48f9e54d058c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[1;31m# Simulate a few rounds of training with the selected client devices.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 31\u001b[1;33m trainer = tff.learning.build_federated_averaging_process(\n\u001b[0m\u001b[0;32m 32\u001b[0m \u001b[0mmodel_fn\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m client_optimizer_fn=lambda: tf.keras.optimizers.SGD(0.1))\n",
|
||||
"\u001b[1;32mD:\\anaconda\\envs\\ml\\lib\\site-packages\\tensorflow_federated\\python\\learning\\federated_averaging.py\u001b[0m in \u001b[0;36mbuild_federated_averaging_process\u001b[1;34m(model_fn, client_optimizer_fn, server_optimizer_fn, client_weight_fn, broadcast_process, aggregation_process, model_update_aggregation_factory, use_experimental_simulation_loop)\u001b[0m\n\u001b[0;32m 221\u001b[0m use_experimental_simulation_loop)\n\u001b[0;32m 222\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 223\u001b[1;33m return optimizer_utils.build_model_delta_optimizer_process(\n\u001b[0m\u001b[0;32m 224\u001b[0m \u001b[0mmodel_fn\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 225\u001b[0m \u001b[0mmodel_to_client_delta_fn\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mclient_fed_avg\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;32mD:\\anaconda\\envs\\ml\\lib\\site-packages\\tensorflow_federated\\python\\learning\\framework\\optimizer_utils.py\u001b[0m in \u001b[0;36mbuild_model_delta_optimizer_process\u001b[1;34m(model_fn, model_to_client_delta_fn, server_optimizer_fn, broadcast_process, aggregation_process, model_update_aggregation_factory)\u001b[0m\n\u001b[0;32m 608\u001b[0m \u001b[0mpy_typecheck\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcheck_callable\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mserver_optimizer_fn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 609\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 610\u001b[1;33m \u001b[0mmodel_weights_type\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmodel_utils\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mweights_type_from_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel_fn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 611\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 612\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mbroadcast_process\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;32mD:\\anaconda\\envs\\ml\\lib\\site-packages\\tensorflow_federated\\python\\learning\\model_utils.py\u001b[0m in \u001b[0;36mweights_type_from_model\u001b[1;34m(model)\u001b[0m\n\u001b[0;32m 98\u001b[0m \u001b[1;31m# with variables created for this model.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 99\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mtf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mGraph\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mas_default\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 100\u001b[1;33m \u001b[0mmodel\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 101\u001b[0m \u001b[0mpy_typecheck\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcheck_type\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmodel_lib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 102\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mtype_conversions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype_from_tensors\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mModelWeights\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfrom_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;32m<ipython-input-2-48f9e54d058c>\u001b[0m in \u001b[0;36mmodel_fn\u001b[1;34m()\u001b[0m\n\u001b[0;32m 22\u001b[0m kernel_initializer='zeros')\n\u001b[0;32m 23\u001b[0m ])\n\u001b[1;32m---> 24\u001b[1;33m return tff.learning.from_keras_model(\n\u001b[0m\u001b[0;32m 25\u001b[0m \u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[0mdummy_batch\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0msample_batch\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;31mTypeError\u001b[0m: from_keras_model() got an unexpected keyword argument 'dummy_batch'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import tensorflow as tf\n",
|
||||
"import tensorflow_federated as tff\n",
|
||||
"\n",
|
||||
"# Load simulation data.\n",
|
||||
"source, _ = tff.simulation.datasets.emnist.load_data()\n",
|
||||
"def client_data(n):\n",
|
||||
" return source.create_tf_dataset_for_client(source.client_ids[n]).map(\n",
|
||||
" lambda e: (tf.reshape(e['pixels'], [-1]), e['label'])\n",
|
||||
" ).repeat(10).batch(20)\n",
|
||||
"\n",
|
||||
"# Pick a subset of client devices to participate in training.\n",
|
||||
"train_data = [client_data(n) for n in range(3)]\n",
|
||||
"\n",
|
||||
"# Grab a single batch of data so that TFF knows what data looks like.\n",
|
||||
"sample_batch = tf.nest.map_structure(\n",
|
||||
" lambda x: x.numpy(), iter(train_data[0]).next())\n",
|
||||
"\n",
|
||||
"# Wrap a Keras model for use with TFF.\n",
|
||||
"def model_fn():\n",
|
||||
" model = tf.keras.models.Sequential([\n",
|
||||
" tf.keras.layers.Dense(10, tf.nn.softmax, input_shape=(784,),\n",
|
||||
" kernel_initializer='zeros')\n",
|
||||
" ])\n",
|
||||
" return tff.learning.from_keras_model(\n",
|
||||
" model,\n",
|
||||
" dummy_batch=sample_batch,\n",
|
||||
" loss=tf.keras.losses.SparseCategoricalCrossentropy(),\n",
|
||||
" metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])\n",
|
||||
"\n",
|
||||
"# Simulate a few rounds of training with the selected client devices.\n",
|
||||
"trainer = tff.learning.build_federated_averaging_process(\n",
|
||||
" model_fn,\n",
|
||||
" client_optimizer_fn=lambda: tf.keras.optimizers.SGD(0.1))\n",
|
||||
"state = trainer.initialize()\n",
|
||||
"for _ in range(5):\n",
|
||||
" state, metrics = trainer.next(state, train_data)\n",
|
||||
" print (metrics.loss)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8-final"
|
||||
},
|
||||
"orig_nbformat": 2,
|
||||
"kernelspec": {
|
||||
"name": "python388jvsc74a57bd05ef0042cb263260037aa2928643ae94e240dd3afaec7872ebebe4f07619ddd0c",
|
||||
"display_name": "Python 3.8.8 64-bit ('ml': conda)"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"# 使用 Python generator 加载数据"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow as tf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def count(stop):\n",
|
||||
" i = 0\n",
|
||||
" while i<stop:\n",
|
||||
" yield i,i+1,i+2\n",
|
||||
" i += 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ds_counter = tf.data.Dataset.from_generator(count, args=[25], output_types=tf.int32, output_shapes = (3,),)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"[[ 0 1 2]\n [ 1 2 3]\n [ 2 3 4]\n [ 3 4 5]\n [ 4 5 6]\n [ 5 6 7]\n [ 6 7 8]\n [ 7 8 9]\n [ 8 9 10]\n [ 9 10 11]]\n[[10 11 12]\n [11 12 13]\n [12 13 14]\n [13 14 15]\n [14 15 16]\n [15 16 17]\n [16 17 18]\n [17 18 19]\n [18 19 20]\n [19 20 21]]\n[[20 21 22]\n [21 22 23]\n [22 23 24]\n [23 24 25]\n [24 25 26]\n [ 0 1 2]\n [ 1 2 3]\n [ 2 3 4]\n [ 3 4 5]\n [ 4 5 6]]\n[[ 5 6 7]\n [ 6 7 8]\n [ 7 8 9]\n [ 8 9 10]\n [ 9 10 11]\n [10 11 12]\n [11 12 13]\n [12 13 14]\n [13 14 15]\n [14 15 16]]\n[[15 16 17]\n [16 17 18]\n [17 18 19]\n [18 19 20]\n [19 20 21]\n [20 21 22]\n [21 22 23]\n [22 23 24]\n [23 24 25]\n [24 25 26]]\n[[ 0 1 2]\n [ 1 2 3]\n [ 2 3 4]\n [ 3 4 5]\n [ 4 5 6]\n [ 5 6 7]\n [ 6 7 8]\n [ 7 8 9]\n [ 8 9 10]\n [ 9 10 11]]\n[[10 11 12]\n [11 12 13]\n [12 13 14]\n [13 14 15]\n [14 15 16]\n [15 16 17]\n [16 17 18]\n [17 18 19]\n [18 19 20]\n [19 20 21]]\n[[20 21 22]\n [21 22 23]\n [22 23 24]\n [23 24 25]\n [24 25 26]\n [ 0 1 2]\n [ 1 2 3]\n [ 2 3 4]\n [ 3 4 5]\n [ 4 5 6]]\n[[ 5 6 7]\n [ 6 7 8]\n [ 7 8 9]\n [ 8 9 10]\n [ 9 10 11]\n [10 11 12]\n [11 12 13]\n [12 13 14]\n [13 14 15]\n [14 15 16]]\n[[15 16 17]\n [16 17 18]\n [17 18 19]\n [18 19 20]\n [19 20 21]\n [20 21 22]\n [21 22 23]\n [22 23 24]\n [23 24 25]\n [24 25 26]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for count_batch in ds_counter.repeat().batch(10).take(10):\n",
|
||||
" print(count_batch.numpy())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": [
|
||||
"## 使用Python生成器解决多个文件加载的问题。\n",
|
||||
"\n",
|
||||
"考虑是否要用这种方式,加载Python生成器中的多个数据。"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8-final"
|
||||
},
|
||||
"orig_nbformat": 2,
|
||||
"kernelspec": {
|
||||
"name": "python388jvsc74a57bd05ef0042cb263260037aa2928643ae94e240dd3afaec7872ebebe4f07619ddd0c",
|
||||
"display_name": "Python 3.8.8 64-bit ('ml': conda)"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"# 1 tf record 实例"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow as tf "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/fsns-20160927/testdata/fsns-00000-of-00001\n",
|
||||
"7905280/7904079 [==============================] - 103s 13us/step\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fsns_test_file = tf.keras.utils.get_file(\"fsns.tfrec\", \"https://storage.googleapis.com/download.tensorflow.org/data/fsns-20160927/testdata/fsns-00000-of-00001\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "execute_result",
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<TFRecordDatasetV2 shapes: (), types: tf.string>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"execution_count": 3
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 使用TFRecordDataset加载二进制的数据\n",
|
||||
"dataset = tf.data.TFRecordDataset(filenames = [fsns_test_file])\n",
|
||||
"dataset"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "execute_result",
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"bytes_list {\n",
|
||||
" value: \"Rue Perreyon\"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"execution_count": 4
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"raw_example = next(iter(dataset))\n",
|
||||
"parsed = tf.train.Example.FromString(raw_example.numpy())\n",
|
||||
"\n",
|
||||
"parsed.features.feature['image/text']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": [
|
||||
"# 2 写入tf example消息格式\n",
|
||||
"第二种加载大数据的方法\n",
|
||||
"\n",
|
||||
"将原来的数据处理成tfrecord格式进行加载。\n",
|
||||
"\n",
|
||||
"## 数据类型\n",
|
||||
"### tf.train.BytesList(可强制转换自以下类型)\n",
|
||||
"* string\n",
|
||||
"* byte\n",
|
||||
"### tf.train.FloatList(可强制转换自以下类型)\n",
|
||||
"* float (float32)\n",
|
||||
"* double (float64)\n",
|
||||
"### tf.train.Int64List(可强制转换自以下类型)\n",
|
||||
"* bool\n",
|
||||
"* enum\n",
|
||||
"* int32\n",
|
||||
"* uint32\n",
|
||||
"* int64\n",
|
||||
"* uint64"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow as tf\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"import IPython.display as display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# The following functions can be used to convert a value to a type compatible\n",
|
||||
"# with tf.Example.\n",
|
||||
"# 定义一系列格式转换函数\n",
|
||||
"\n",
|
||||
"def _bytes_feature(value):\n",
|
||||
" \"\"\"Returns a bytes_list from a string / byte.\"\"\"\n",
|
||||
" if isinstance(value, type(tf.constant(0))):\n",
|
||||
" value = value.numpy() # BytesList won't unpack a string from an EagerTensor.\n",
|
||||
" return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n",
|
||||
"\n",
|
||||
"def _float_feature(value):\n",
|
||||
" \"\"\"Returns a float_list from a float / double.\"\"\"\n",
|
||||
" return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))\n",
|
||||
"\n",
|
||||
"def _int64_feature(value):\n",
|
||||
" \"\"\"Returns an int64_list from a bool / enum / int / uint.\"\"\"\n",
|
||||
" return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"bytes_list {\n value: \"test_string\"\n}\n\nbytes_list {\n value: \"test_bytes\"\n}\n\nfloat_list {\n value: 2.7182817\n}\n\nint64_list {\n value: 1\n}\n\nint64_list {\n value: 1\n}\n\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(_bytes_feature(b'test_string'))\n",
|
||||
"print(_bytes_feature(u'test_bytes'.encode('utf-8')))\n",
|
||||
"\n",
|
||||
"print(_float_feature(np.exp(1)))\n",
|
||||
"\n",
|
||||
"print(_int64_feature(True))\n",
|
||||
"print(_int64_feature(1))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "execute_result",
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"b'\\x12\\x06\\n\\x04T\\xf8-@'"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"execution_count": 9
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# serializetostring()格式化为二进制字符串\n",
|
||||
"feature = _float_feature(np.exp(1))\n",
|
||||
"\n",
|
||||
"feature.SerializeToString()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": [
|
||||
"# 3 读取tf example 消息格式"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8-final"
|
||||
},
|
||||
"orig_nbformat": 2,
|
||||
"kernelspec": {
|
||||
"name": "python388jvsc74a57bd05ef0042cb263260037aa2928643ae94e240dd3afaec7872ebebe4f07619ddd0c",
|
||||
"display_name": "Python 3.8.8 64-bit ('ml': conda)"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2,
|
||||
"cells": [
|
||||
{
|
||||
"source": [
|
||||
"# 1使用tf.TextLineReader"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow as tf "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"directory_url = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'\n",
|
||||
"file_names = ['cowper.txt', 'derby.txt', 'butler.txt']\n",
|
||||
"\n",
|
||||
"file_paths = [\n",
|
||||
" tf.keras.utils.get_file(file_name, directory_url + file_name)\n",
|
||||
" for file_name in file_names\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"b\"\\xef\\xbb\\xbfAchilles sing, O Goddess! Peleus' son;\"\nb'His wrath pernicious, who ten thousand woes'\nb\"Caused to Achaia's host, sent many a soul\"\nb'Illustrious into Ades premature,'\nb'And Heroes gave (so stood the will of Jove)'\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 使用textlinedataset一次读取某个文件中的一行\n",
|
||||
"dataset = tf.data.TextLineDataset(file_paths)\n",
|
||||
"for line in dataset.take(5):\n",
|
||||
" print(line.numpy())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": [
|
||||
"# 2 使用interleave进行读取?"
|
||||
],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\nb\"\\xef\\xbb\\xbfAchilles sing, O Goddess! Peleus' son;\"\nb\"\\xef\\xbb\\xbfOf Peleus' son, Achilles, sing, O Muse,\"\nb'\\xef\\xbb\\xbfSing, O goddess, the anger of Achilles son of Peleus, that brought'\n\nb'His wrath pernicious, who ten thousand woes'\nb'The vengeance, deep and deadly; whence to Greece'\nb'countless ills upon the Achaeans. Many a brave soul did it send'\n\nb\"Caused to Achaia's host, sent many a soul\"\nb'Unnumbered ills arose; which many a soul'\nb'hurrying down to Hades, and many a hero did it yield a prey to dogs and'\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 要在文件之间替换,请使用Dataset.interleave。这样可以更轻松地将文件混在一起。这是每种翻译的第一,第二和第三行:\n",
|
||||
"# 这种方法可以一次读取多个文件的数据,并混合起来诶!!!666\n",
|
||||
"files_ds = tf.data.Dataset.from_tensor_slices(file_paths)\n",
|
||||
"lines_ds = files_ds.interleave(tf.data.TextLineDataset, cycle_length=3)\n",
|
||||
"\n",
|
||||
"for i, line in enumerate(lines_ds.take(9)):\n",
|
||||
" if i % 3 == 0:\n",
|
||||
" print()\n",
|
||||
" print(line.numpy())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Downloading data from https://storage.googleapis.com/tf-datasets/titanic/train.csv\n",
|
||||
"32768/30874 [===============================] - 0s 10us/step\n",
|
||||
"b'survived,sex,age,n_siblings_spouses,parch,fare,class,deck,embark_town,alone'\n",
|
||||
"b'0,male,22.0,1,0,7.25,Third,unknown,Southampton,n'\n",
|
||||
"b'1,female,38.0,1,0,71.2833,First,C,Cherbourg,n'\n",
|
||||
"b'1,female,26.0,0,0,7.925,Third,unknown,Southampton,y'\n",
|
||||
"b'1,female,35.0,1,0,53.1,First,C,Southampton,n'\n",
|
||||
"b'0,male,28.0,0,0,8.4583,Third,unknown,Queenstown,y'\n",
|
||||
"b'0,male,2.0,3,1,21.075,Third,unknown,Southampton,n'\n",
|
||||
"b'1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n'\n",
|
||||
"b'1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n'\n",
|
||||
"b'1,female,4.0,1,1,16.7,Third,G,Southampton,n'\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# TextLineDataset产生每个文件的每一行,这可能是不希望的,例如,如果文件以标题行开头或包含注释。可以使用Dataset.skip()或 Dataset.filter()转换删除这些行。在这里,您跳过第一行,然后过滤以仅查找幸存者。\n",
|
||||
"titanic_file = tf.keras.utils.get_file(\"train.csv\", \"https://storage.googleapis.com/tf-datasets/titanic/train.csv\")\n",
|
||||
"titanic_lines = tf.data.TextLineDataset(titanic_file)\n",
|
||||
"\n",
|
||||
"for line in titanic_lines.take(10):\n",
|
||||
" print(line.numpy())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"b'1,female,38.0,1,0,71.2833,First,C,Cherbourg,n'\nb'1,female,26.0,0,0,7.925,Third,unknown,Southampton,y'\nb'1,female,35.0,1,0,53.1,First,C,Southampton,n'\nb'1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n'\nb'1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n'\nb'1,female,4.0,1,1,16.7,Third,G,Southampton,n'\nb'1,male,28.0,0,0,13.0,Second,unknown,Southampton,y'\nb'1,female,28.0,0,0,7.225,Third,unknown,Cherbourg,y'\nb'1,male,28.0,0,0,35.5,First,A,Southampton,y'\nb'1,female,38.0,1,5,31.3875,Third,unknown,Southampton,n'\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def survived(line):\n",
|
||||
" return tf.not_equal(tf.strings.substr(line, 0, 1), \"0\")\n",
|
||||
"\n",
|
||||
"survivors = titanic_lines.skip(1).filter(survived)\n",
|
||||
"\n",
|
||||
"for line in survivors.take(10):\n",
|
||||
" print(line.numpy())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
### TensorFlow
|
||||
|
||||
- [x] 复习教程(包括tutorial、API、code)
|
||||
- [ ] TensorFlow 数据流水线技术
|
||||
- [x] TensorFlow 数据流水线技术
|
||||
- [ ] 学习TensorFlow框架并应用
|
||||
- [ ] 学习TensorFlow federated框架并应用
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
> 一期简历
|
||||
|
||||
## 腾讯实习
|
||||
## ~~腾讯实习~~
|
||||
|
||||
* 岗位:后端开发——微信事业群
|
||||
* 技术要求:
|
||||
@@ -60,6 +60,7 @@
|
||||
- [x] 简历投递https://jobs.bytedance.com/campus/position/application
|
||||
- [x] 2021-04-11 15:00 1面。北京字节跳动。
|
||||
- [x] 2021-04-14 11:00 3面。
|
||||
- [ ] 结果未知,生死未卜
|
||||
|
||||
## 阿里巴巴
|
||||
* 岗位:研发工程师C++
|
||||
@@ -74,6 +75,7 @@
|
||||
- [x] 素质测评
|
||||
- [x] 2021年04月09日 19:00 - 2021年04月09日 20:00。完球了没人捞我的专利,待会问问师兄。
|
||||
- [x] 2021年4月19日 16:00 一面。终于还是来了。还是要好好准备的。把所有的问题复习一遍。估计很难进。
|
||||
- [ ] 2021年4月23日 15:00 三面。
|
||||
|
||||
> 二期简历
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
系列一数据库数据表的创建等基本操作
|
||||
# 系列一 数据库数据表的创建等基本操作
|
||||
```sql
|
||||
#注释内容(与python很像)
|
||||
-- 也为注释内容
|
||||
@@ -1,4 +1,7 @@
|
||||
系列十子查询 &正则表达式查询 &运算符的使用
|
||||
# 系列十 子查询 &正则表达式查询 &运算符的使用
|
||||
> * 子查询
|
||||
> * 正则表达式查询
|
||||
> * 运算符的使用
|
||||
```sql
|
||||
#第四十二课时
|
||||
--子查询的使用
|
||||
@@ -1,4 +1,10 @@
|
||||
系列十一函数与表达式的应用
|
||||
|
||||
> * 数学函数
|
||||
> * 字符串函数
|
||||
> * 日期时间函数
|
||||
> * 条件判断函数和系统函数
|
||||
|
||||
```sql
|
||||
#第四十六课时
|
||||
--数学函数库中的函数
|
||||
@@ -1,4 +1,7 @@
|
||||
系列十二索引的使用和数据库的管理
|
||||
|
||||
> * 索引的使用
|
||||
> * 管理数据库
|
||||
```sql
|
||||
#第五十一课时
|
||||
--索引的使用
|
||||
@@ -1,4 +1,4 @@
|
||||
数据类型的测试
|
||||
# 系列二 数据类型的测试
|
||||
```sql
|
||||
# 第八课时数据测试
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
系列三完整性约束条件
|
||||
# 3 系列三 完整性约束条件
|
||||
|
||||
> * 主键约束
|
||||
> * 自增长
|
||||
> * 默认值和非空约束
|
||||
> * 唯一约束
|
||||
|
||||
```sql
|
||||
#第十二课时测试主键长度
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
系列四数据表结构的相关操作
|
||||
# 系类四 数据表结构的相关操作
|
||||
> * 修改表名称
|
||||
> * 添加删除字段
|
||||
> * 修改字段和完整性约束条件
|
||||
|
||||
|
||||
```sql
|
||||
#第十七课时修改表名称
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
系列五 对表中数据的操作
|
||||
# 系列五 对表中数据的操作
|
||||
|
||||
> * 插入记录
|
||||
> * 更新和删除记录
|
||||
```sql
|
||||
#第二十四课时插入记录
|
||||
--插入记录的操作
|
||||
@@ -1,4 +1,9 @@
|
||||
系列六表达式与查询
|
||||
# 系列六 表达式与查询
|
||||
> * 查询表达式
|
||||
> * 带条件的查询
|
||||
> * 范围查询
|
||||
> * 模糊查询
|
||||
> * 逻辑运算符查询
|
||||
```sql
|
||||
--SELECT 之后表示要查询的字段
|
||||
--FROM 之后表示要查询的数据库和表的名称
|
||||
@@ -1,4 +1,9 @@
|
||||
系列七高级的查询功能
|
||||
# 系列七 高级的查询功能
|
||||
> * 分组查询group by
|
||||
> * 聚合函数avg
|
||||
> * 分组筛选having
|
||||
> * 结果排序order by
|
||||
> * 限制数量limit
|
||||
```sql
|
||||
|
||||
#第三十一课时
|
||||
@@ -1,4 +1,7 @@
|
||||
系列八条件语句在各个部分的应用更新,插入,删除记录的中的数据
|
||||
# 系列八 条件语句在各个部分的应用
|
||||
> 更新,插入,删除记录的中的数据
|
||||
> * 条件更新、条件删除
|
||||
> * 连接查询
|
||||
```sql
|
||||
#第三十六课时
|
||||
--条件更新
|
||||
@@ -1,4 +1,7 @@
|
||||
系列九外键的相关操作
|
||||
# 系列九 外键的相关操作
|
||||
> * 外键操作
|
||||
> * 外键的创建、删除
|
||||
> * 联合查询
|
||||
```sql
|
||||
#第三十九课时
|
||||
--外键操作
|
||||
BIN
数据库/MySQL/image/2021-04-23-12-41-46.png
Normal file
BIN
数据库/MySQL/image/2021-04-23-12-41-46.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
BIN
数据库/MySQL/image/2021-04-23-12-46-47.png
Normal file
BIN
数据库/MySQL/image/2021-04-23-12-46-47.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
163
数据库/MySQL/附录1 MySQL存储引擎.md
Normal file
163
数据库/MySQL/附录1 MySQL存储引擎.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# MySQL存储引擎
|
||||
|
||||
## 1 概述
|
||||
### 存储引擎
|
||||
|
||||
1. MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。
|
||||
|
||||
2. 例如,如果你在研究大量的临时数据,你也许需要使用内存MySQL存储引擎。内存存储引擎能够在内存中存储所有的表格数据。又或者,你也许需要一个支持事务处理的数据库(以确保事务处理不成功时数据的回退能力)。
|
||||
3. 这些不同的技术以及配套的相关功能在 MySQL中被称作存储引擎(也称作表类型)。 MySQL默认配置了许多不同的存储引擎,可以预先设置或者在MySQL服务器中启用。你可以选择适用于服务器、数据库和表格的存储引擎,以便在选择如何存储你的信息、如何检索这些信息以及你需要你的数据结合什么性能和功能的时候为你提供最大的灵活性。
|
||||
|
||||
### MySQL支持的存储引擎
|
||||

|
||||
|
||||
|
||||
### 存储引擎对比
|
||||
|
||||
| 功 能 | MYISAM | Memory | InnoDB | Archive |
|
||||
|--------|--------|--------|--------|---------|
|
||||
| 存储限制 | 256TB | RAM | 64TB | None |
|
||||
| 支持事物 | No | No | Yes | No |
|
||||
| 支持全文索引 | Yes | No | No | No |
|
||||
| 支持数索引 | Yes | Yes | Yes | No |
|
||||
| 支持哈希索引 | No | Yes | No | No |
|
||||
| 支持数据缓存 | No | N/A | Yes | No |
|
||||
| 支持外键 | No | No | Yes | No |
|
||||
|
||||
|
||||
|
||||
## 2.1 MyISAM
|
||||
|
||||
### 存储引擎的实现
|
||||
使用这个存储引擎,每个MyISAM在磁盘上存储成三个文件。
|
||||
|
||||
1. frm文件:存储表的定义数据
|
||||
2. MYD文件:存放表具体记录的数据
|
||||
3. MYI文件:存储索引
|
||||
|
||||
frm和MYI可以存放在不同的目录下。MYI文件用来存储索引,但仅保存记录所在页的指针,索引的结构是B+树结构。下面这张图就是MYI文件保存的机制:
|
||||
|
||||

|
||||
|
||||
从这张图可以发现,这个存储引擎通过MYI的B+树结构来查找记录页,再根据记录页查找记录。并且支持全文索引、B树索引和数据压缩。
|
||||
|
||||
### 支持数据的类型
|
||||
|
||||
1. 静态固定长度表。这种方式的优点在于存储速度非常快,容易发生缓存,而且表发生损坏后也容易修复。缺点是占空间。这也是默认的存储格式。
|
||||
2. 动态可变长表。优点是节省空间,但是一旦出错恢复起来比较麻烦。
|
||||
3. 压缩表。上面说到支持数据压缩,说明肯定也支持这个格式。在数据文件发生错误时候,可以使用check table工具来检查,而且还可以使用repair table工具来恢复。
|
||||
|
||||
### 存储引擎的特点
|
||||
有一个重要的特点那就是不支持事务,但是这也意味着他的存储速度更快,如果你的读写操作允许有错误数据的话,只是追求速度,可以选择这个存储引擎。
|
||||
|
||||
MyISAM存储引擎
|
||||
|
||||
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物。MyISAM主要特性有:
|
||||
|
||||
1. 大文件(达到63位文件长度)在支持大文件的文件系统和操作系统上被支持
|
||||
|
||||
2. 当把删除和更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展到下一块自动完成
|
||||
|
||||
3. 每个MyISAM表最大索引数是64,这可以通过重新编译来改变。每个索引最大的列数是16
|
||||
|
||||
4. 最大的键长度是1000字节,这也可以通过编译来改变,对于键长度超过250字节的情况,一个超过1024字节的键将被用上
|
||||
|
||||
5. BLOB和TEXT列可以被索引
|
||||
|
||||
6. NULL被允许在索引的列中,这个值占每个键的0~1个字节
|
||||
|
||||
7. 所有数字键值以高字节优先被存储以允许一个更高的索引压缩
|
||||
|
||||
8. 每个MyISAM类型的表都有一个AUTO_INCREMENT的内部列,当INSERT和UPDATE操作的时候该列被更新,同时AUTO_INCREMENT列将被刷新。所以说,MyISAM类型表的AUTO_INCREMENT列更新比InnoDB类型的AUTO_INCREMENT更快
|
||||
|
||||
9. 可以把数据文件和索引文件放在不同目录
|
||||
|
||||
10. 每个字符列可以有不同的字符集
|
||||
|
||||
11. 有VARCHAR的表可以固定或动态记录长度
|
||||
|
||||
12. VARCHAR和CHAR列可以多达64KB
|
||||
|
||||
## 2.2 InnoDB
|
||||
|
||||
### 存储引擎的特点
|
||||
InnoDB是默认的数据库存储引擎,他的主要特点有:
|
||||
> 对于InnoDB来说,最大的特点在于支持事务。但是这是以损失效率来换取的。
|
||||
1. 可以通过自动增长列,方法是auto_increment。
|
||||
2. 支持事务。默认的事务隔离级别为可重复度,通过MVCC(并发版本控制)来实现的。
|
||||
3. 使用的锁粒度为行级锁,可以支持更高的并发;
|
||||
4. 支持外键约束;外键约束其实降低了表的查询速度,但是增加了表之间的耦合度。
|
||||
5. 配合一些热备工具可以支持在线热备份;
|
||||
6. 在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度;
|
||||
7. 对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+数的叶子节点上;
|
||||
|
||||
### 存储引擎的实现
|
||||
当然InnoDB的存储表和索引也有下面两种形式:
|
||||
|
||||
1. 使用共享表空间存储:所有的表和索引存放在同一个表空间中。
|
||||
|
||||
2. 使用多表空间存储:表结构放在frm文件,数据和索引放在IBD文件中。分区表的话,每个分区对应单独的IBD文件,分区表的定义可以查看我的其他文章。使用分区表的好处在于提升查询效率。
|
||||
|
||||
### InnoDB索引和MyISAM索引的区别:
|
||||
|
||||
一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
|
||||
|
||||
二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。
|
||||
### 存储引擎的特点2
|
||||
|
||||
> InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,上图也看到了,InnoDB是默认的MySQL引擎。InnoDB主要特性有:
|
||||
|
||||
1. InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事物安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供一个类似Oracle的非锁定读。这些功能增加了多用户部署和性能。在SQL查询中,可以自由地将InnoDB类型的表和其他MySQL的表类型混合起来,甚至在同一个查询中也可以混合
|
||||
|
||||
2. InnoDB是为处理巨大数据量的最大性能设计。它的CPU效率可能是任何其他基于磁盘的关系型数据库引擎锁不能匹敌的
|
||||
|
||||
3. InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB将它的表和索引在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘文件)。这与MyISAM表不同,比如在MyISAM表中每个表被存放在分离的文件中。InnoDB表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上
|
||||
|
||||
4. InnoDB支持外键完整性约束,存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB会为每一行生成一个6字节的ROWID,并以此作为主键
|
||||
|
||||
5. InnoDB被用在众多需要高性能的大型数据库站点上。InnoDB不创建目录,使用InnoDB时,MySQL将在MySQL数据目录下创建一个名为ibdata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件
|
||||
|
||||
## 2.3 Memory
|
||||
|
||||
### 存储引擎的实现
|
||||
将数据存在内存,为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联。文件是frm。
|
||||
|
||||
1. 支持的数据类型有限制,比如:不支持TEXT和BLOB类型,对于字符串类型的数据,只支持固定长度的行,VARCHAR会被自动存储为CHAR类型;
|
||||
2. 支持的锁粒度为表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈;
|
||||
3. 由于数据是存放在内存中,一旦服务器出现故障,数据都会丢失;
|
||||
4. 查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低;
|
||||
5. 默认使用hash索引。
|
||||
6. 如果一个内部表很大,会转化为磁盘表。
|
||||
|
||||
|
||||
### 存储引擎的特点
|
||||
|
||||
MEMORY存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问。MEMORY主要特性有:
|
||||
|
||||
1. MEMORY表的每个表可以有多达32个索引,每个索引16列,以及500字节的最大键长度
|
||||
|
||||
2. MEMORY存储引擎执行HASH和BTREE缩影
|
||||
|
||||
3. 可以在一个MEMORY表中有非唯一键值
|
||||
|
||||
4. MEMORY表使用一个固定的记录长度格式
|
||||
|
||||
5. MEMORY不支持BLOB或TEXT列
|
||||
|
||||
6. MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引
|
||||
|
||||
7. MEMORY表在所由客户端之间共享(就像其他任何非TEMPORARY表)
|
||||
|
||||
8. MEMORY表内存被存储在内存中,内存是MEMORY表和服务器在查询处理时的空闲中,创建的内部表共享
|
||||
|
||||
9. 当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行DELETE FROM或TRUNCATE TABLE,或者删除整个表(使用DROP TABLE)
|
||||
|
||||
## 2.4 MERGE
|
||||
|
||||
1. MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须完全相同,尽管其使用不如其它引擎突出,但是在某些情况下非常有用。说白了,Merge表就是几个相同MyISAM表的聚合器;Merge表中并没有数据,对Merge类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行操作。Merge存储引擎的使用场景。
|
||||
|
||||
2. 对于服务器日志这种信息,一般常用的存储策略是将数据分成很多表,每个名称与特定的时间端相关。例如:可以用12个相同的表来存储服务器日志数据,每个表用对应各个月份的名字来命名。当有必要基于所有12个日志表的数据来生成报表,这意味着需要编写并更新多表查询,以反映这些表中的信息。与其编写这些可能出现错误的查询,不如将这些表合并起来使用一条查询,之后再删除Merge表,而不影响原来的数据,删除Merge表只是删除Merge表的定义,对内部的表没有任何影响。
|
||||
|
||||
## 2.5 ARCHIVE
|
||||
|
||||
1. Archive是归档的意思,在归档之后很多的高级功能就不再支持了,仅仅支持最基本的插入和查询两种功能。在MySQL 5.5版以前,Archive是不支持索引,但是在MySQL 5.5以后的版本中就开始支持索引了。Archive拥有很好的压缩机制,它使用zlib压缩库,在记录被请求时会实时压缩,所以它经常被用来当做仓库使用。
|
||||
264
数据库/MySQL/附录2 MySql性能优化.md
Normal file
264
数据库/MySQL/附录2 MySql性能优化.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# 10个MySQL性能调优的方法
|
||||
> 参考文献
|
||||
> * [https://www.jb51.net/article/70111.htm](https://www.jb51.net/article/70111.htm)
|
||||
> * [https://www.cnblogs.com/jiekzou/p/5371085.html](https://www.cnblogs.com/jiekzou/p/5371085.html)
|
||||
|
||||
## 0 基础方法
|
||||
|
||||
1. 数据库设计优化:
|
||||
1. 选择合适的存储引擎
|
||||
2. 设计合理的表结构(符合3NF)
|
||||
3. 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
|
||||
2. 查询语句优化:
|
||||
1. 通过show status命令了解各种SQL的执行频率。
|
||||
2. 定位执行效率较低的SQL语句-(重点select,记录慢查询)
|
||||
3. 通过explain分析低效率的SQL
|
||||
3. 查询过程优化
|
||||
1. 从内存中读取数据
|
||||
2. 减少磁盘写入操作(更大的写缓存)
|
||||
3. 提高磁盘读取速度
|
||||
## 1 选择合适的存储引擎: InnoDB
|
||||
|
||||
* 除非你的数据表使用来做只读或者全文检索 (相信现在提到全文检索,没人会用 MYSQL 了),你应该默认选择 InnoDB 。
|
||||
|
||||
* 你自己在测试的时候可能会发现 MyISAM 比 InnoDB 速度快,这是因为: MyISAM 只缓存索引,而 InnoDB 缓存数据和索引,MyISAM 不支持事务。但是 如果你使用 innodb_flush_log_at_trx_commit = 2 可以获得接近的读取性能 (相差百倍) 。
|
||||
|
||||
### 1.1 如何将现有的 MyISAM 数据库转换为 InnoDB:
|
||||
|
||||
```
|
||||
mysql -u [USER_NAME] -p -e "SHOW TABLES IN [DATABASE_NAME];" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=InnoDB;" > alter_table.sql
|
||||
|
||||
perl -p -i -e 's/(search_[a-z_]+ ENGINE=)InnoDB//1MyISAM/g' alter_table.sql
|
||||
|
||||
mysql -u [USER_NAME] -p [DATABASE_NAME] < alter_table.sql
|
||||
|
||||
mysql -u [USER_NAME] -p -e "SHOW TABLES IN [DATABASE_NAME];" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=InnoDB;" > alter_table.sql
|
||||
|
||||
perl -p -i -e 's/(search_[a-z_]+ ENGINE=)InnoDB//1MyISAM/g' alter_table.sql
|
||||
|
||||
mysql -u [USER_NAME] -p [DATABASE_NAME] < alter_table.sql
|
||||
```
|
||||
### 1.2 为每个表分别创建 InnoDB FILE:
|
||||
|
||||
```
|
||||
innodb_file_per_table=1
|
||||
```
|
||||
这样可以保证 ibdata1 文件不会过大,失去控制。尤其是在执行 mysqlcheck -o –all-databases 的时候。
|
||||
|
||||
|
||||
|
||||
## 2. 保证从内存中读取数据,讲数据保存在内存中
|
||||
|
||||
### 2.1 足够大的 innodb_buffer_pool_size
|
||||
|
||||
推荐将数据完全保存在 innodb_buffer_pool_size ,即按存储量规划 innodb_buffer_pool_size 的容量。这样你可以完全从内存中读取数据,最大限度减少磁盘操作。
|
||||
|
||||
第一步:如何确定 innodb_buffer_pool_size 足够大,数据是从内存读取而不是硬盘?
|
||||
|
||||
查询buffer size
|
||||
```
|
||||
mysql> SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_%';
|
||||
+----------------------------------+--------+
|
||||
| Variable_name | Value |
|
||||
+----------------------------------+--------+
|
||||
| Innodb_buffer_pool_pages_data | 129037 |
|
||||
| Innodb_buffer_pool_pages_dirty | 362 |
|
||||
| Innodb_buffer_pool_pages_flushed | 9998 |
|
||||
| Innodb_buffer_pool_pages_free | 0 | !!!!!!!!
|
||||
| Innodb_buffer_pool_pages_misc | 2035 |
|
||||
| Innodb_buffer_pool_pages_total | 131072 |
|
||||
+----------------------------------+--------+
|
||||
6 rows in set (0.00 sec)
|
||||
|
||||
innodb_additional_mem_pool_size = 1/200 of buffer_pool
|
||||
innodb_max_dirty_pages_pct 80%
|
||||
```
|
||||
发现 Innodb_buffer_pool_pages_free 为 0,则说明 buffer pool 已经被用光,需要增大 innodb_buffer_pool_size
|
||||
|
||||
或者用iostat -d -x -k 1 命令,查看硬盘的操作。
|
||||
|
||||
第二步:服务器上是否有足够内存用来规划。执行 echo 1 > /proc/sys/vm/drop_caches 清除操作系统的文件缓存,可以看到真正的内存使用量。
|
||||
|
||||
### 2.2 数据预热
|
||||
|
||||
默认情况,只有某条数据被读取一次,才会缓存在 innodb_buffer_pool。所以,数据库刚刚启动,需要进行数据预热,将磁盘上的所有数据缓存到内存中。数据预热可以提高读取速度。
|
||||
|
||||
对于 InnoDB 数据库,可以用以下方法,进行数据预热:
|
||||
|
||||
1. 将以下脚本保存为 MakeSelectQueriesToLoad.sql
|
||||
|
||||
```
|
||||
SELECT DISTINCT
|
||||
CONCAT('SELECT ',ndxcollist,' FROM ',db,'.',tb,
|
||||
' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
engine,table_schema db,table_name tb,
|
||||
index_name,GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
B.engine,A.table_schema,A.table_name,
|
||||
A.index_name,A.column_name,A.seq_in_index
|
||||
FROM
|
||||
information_schema.statistics A INNER JOIN
|
||||
(
|
||||
SELECT engine,table_schema,table_name
|
||||
FROM information_schema.tables WHERE
|
||||
engine='InnoDB'
|
||||
) B USING (table_schema,table_name)
|
||||
WHERE B.table_schema NOT IN ('information_schema','mysql')
|
||||
ORDER BY table_schema,table_name,index_name,seq_in_index
|
||||
) A
|
||||
GROUP BY table_schema,table_name,index_name
|
||||
) AA
|
||||
ORDER BY db,tb;
|
||||
```
|
||||
2. 执行
|
||||
```
|
||||
mysql -uroot -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql
|
||||
```
|
||||
3. 每次重启数据库,或者整库备份前需要预热的时候执行:
|
||||
```
|
||||
mysql -uroot < /root/SelectQueriesToLoad.sql > /dev/null 2>&1
|
||||
```
|
||||
|
||||
### 2.3 不要让数据存到 SWAP 中
|
||||
|
||||
如果是专用 MYSQL 服务器,可以禁用 SWAP,如果是共享服务器,确定 innodb_buffer_pool_size 足够大。或者使用固定的内存空间做缓存,使用 memlock 指令。
|
||||
|
||||
|
||||
|
||||
## 3 定期优化重建数据库
|
||||
|
||||
mysqlcheck -o –all-databases 会让 ibdata1 不断增大,真正的优化只有重建数据表结构:
|
||||
```
|
||||
CREATE TABLE mydb.mytablenew LIKE mydb.mytable;
|
||||
INSERT INTO mydb.mytablenew SELECT * FROM mydb.mytable;
|
||||
ALTER TABLE mydb.mytable RENAME mydb.mytablezap;
|
||||
ALTER TABLE mydb.mytablenew RENAME mydb.mytable;
|
||||
DROP TABLE mydb.mytablezap;
|
||||
```
|
||||
|
||||
## 4 减少磁盘写入操作
|
||||
|
||||
### 4.1 使用足够大的写入缓存 innodb_log_file_size
|
||||
|
||||
但是需要注意如果用 1G 的 innodb_log_file_size ,假如服务器当机,需要 10 分钟来恢复。
|
||||
|
||||
推荐 innodb_log_file_size 设置为 0.25 * innodb_buffer_pool_size
|
||||
|
||||
### 4.2 innodb_flush_log_at_trx_commit
|
||||
|
||||
这个选项和写磁盘操作密切相关:
|
||||
|
||||
innodb_flush_log_at_trx_commit = 1 则每次修改写入磁盘
|
||||
innodb_flush_log_at_trx_commit = 0/2 每秒写入磁盘
|
||||
|
||||
如果你的应用不涉及很高的安全性 (金融系统),或者基础架构足够安全,或者 事务都很小,都可以用 0 或者 2 来降低磁盘操作。
|
||||
|
||||
### 4.3 避免双写入缓冲
|
||||
```
|
||||
innodb_flush_method=O_DIRECT
|
||||
```
|
||||
|
||||
## 5 提高磁盘读写速度
|
||||
|
||||
RAID0 尤其是在使用 EC2 这种虚拟磁盘 (EBS) 的时候,使用软 RAID0 非常重要。
|
||||
|
||||
|
||||
|
||||
## 6 充分使用索引
|
||||
|
||||
### 6.1 查看现有表结构和索引
|
||||
```
|
||||
SHOW CREATE TABLE db1.tb1/G
|
||||
```
|
||||
### 6.2 添加必要的索引
|
||||
|
||||
索引是提高查询速度的唯一方法,比如搜索引擎用的倒排索引是一样的原理。
|
||||
|
||||
索引的添加需要根据查询来确定,比如通过慢查询日志或者查询日志,或者通过 EXPLAIN 命令分析查询。
|
||||
|
||||
```
|
||||
ADD UNIQUE INDEX
|
||||
ADD INDEX
|
||||
```
|
||||
|
||||
### 6.3 实例:优化用户验证表:
|
||||
添加索引
|
||||
|
||||
```
|
||||
ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
|
||||
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);
|
||||
```
|
||||
每次重启服务器进行数据预热
|
||||
```
|
||||
echo “select username,password from users;” > /var/lib/mysql/upcache.sql
|
||||
```
|
||||
添加启动脚本到 my.cnf
|
||||
```
|
||||
[mysqld]
|
||||
init-file=/var/lib/mysql/upcache.sql
|
||||
```
|
||||
### 6.4 实例:使用自动加索引的框架或者自动拆分表结构的框架
|
||||
比如,Rails 这样的框架,会自动添加索引,Drupal 这样的框架会自动拆分表结构。会在你开发的初期指明正确的方向。所以,经验不太丰富的人一开始就追求从 0 开始构建,实际是不好的做法。
|
||||
|
||||
## 7 分析查询日志和慢查询日志
|
||||
修改mysql的慢查询.
|
||||
```
|
||||
show variables like 'long_query_time' ; //可以显示当前慢查询时间
|
||||
set long_query_time=1 ;//可以修改慢查询时间
|
||||
```
|
||||
记录所有查询,这在用 ORM 系统或者生成查询语句的系统很有用。
|
||||
```
|
||||
log=/var/log/mysql.log
|
||||
```
|
||||
注意不要在生产环境用,否则会占满你的磁盘空间。
|
||||
|
||||
记录执行时间超过 1 秒的查询:
|
||||
```
|
||||
long_query_time=1
|
||||
log-slow-queries=/var/log/mysql/log-slow-queries.log
|
||||
```
|
||||
|
||||
### explain查询语句
|
||||
|
||||
Explain select * from emp where ename=“wsrcla”
|
||||
会产生如下信息:
|
||||
select_type:表示查询的类型。
|
||||
table:输出结果集的表
|
||||
type:表示表的连接类型
|
||||
possible_keys:表示查询时,可能使用的索引
|
||||
key:表示实际使用的索引
|
||||
key_len:索引字段的长度
|
||||
rows:扫描出的行数(估算的行数)
|
||||
Extra:执行情况的描述和说明
|
||||
|
||||
## 8 激进的方法,使用内存磁盘
|
||||
|
||||
现在基础设施的可靠性已经非常高了,比如 EC2 几乎不用担心服务器硬件当机。而且内存实在是便宜,很容易买到几十G内存的服务器,可以用内存磁盘,定期备份到磁盘。
|
||||
|
||||
将 MYSQL 目录迁移到 4G 的内存磁盘
|
||||
```
|
||||
mkdir -p /mnt/ramdisk
|
||||
sudo mount -t tmpfs -o size=4000M tmpfs /mnt/ramdisk/
|
||||
mv /var/lib/mysql /mnt/ramdisk/mysql
|
||||
ln -s /tmp/ramdisk/mysql /var/lib/mysql
|
||||
chown mysql:mysql mysql
|
||||
```
|
||||
## 9 用 NOSQL 的方式使用 MYSQL
|
||||
|
||||
B-TREE 仍然是最高效的索引之一,所有 MYSQL 仍然不会过时。
|
||||
|
||||
用 HandlerSocket 跳过 MYSQL 的 SQL 解析层,MYSQL 就真正变成了 NOSQL。
|
||||
|
||||
## 10 其他
|
||||
|
||||
1. 单条查询最后增加 LIMIT 1,停止全表扫描。
|
||||
2. 将非”索引”数据分离,比如将大篇文章分离存储,不影响其他自动查询。
|
||||
3. 不用 MYSQL 内置的函数,因为内置函数不会建立查询缓存。
|
||||
4. PHP 的建立连接速度非常快,所有可以不用连接池,否则可能会造成超过连接数。当然不用连接池 PHP 程序也可能将
|
||||
5. 连接数占满比如用了 @ignore_user_abort(TRUE);
|
||||
6. 使用 IP 而不是域名做数据库路径,避免 DNS 解析问题
|
||||
1
数据库/Redis/附录3 Redis数据结构.md
Normal file
1
数据库/Redis/附录3 Redis数据结构.md
Normal file
@@ -0,0 +1 @@
|
||||
https://www.cnblogs.com/ysocean/p/9080942.html#_label1
|
||||
@@ -19,4 +19,20 @@
|
||||
|
||||
1. 事务(ACID automatic consistency isolation durability)
|
||||
2. 并发一致性的问题。脏读、不可重复读、丢失修改
|
||||
3. 兵法一致性的方案。读写锁:互斥锁、共享锁。三级封锁协议。
|
||||
3. 兵法一致性的方案。读写锁:互斥锁、共享锁。三级封锁协议。
|
||||
|
||||
## 6 性能优化
|
||||
|
||||
|
||||
1. 数据库设计优化:
|
||||
1. 选择合适的存储引擎
|
||||
2. 设计合理的表结构(符合3NF)
|
||||
3. 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
|
||||
2. 查询语句优化:
|
||||
1. 通过show status命令了解各种SQL的执行频率。
|
||||
2. 定位执行效率较低的SQL语句-(重点select,记录慢查询)
|
||||
3. 通过explain分析低效率的SQL
|
||||
3. 查询过程优化
|
||||
1. 从内存中读取数据
|
||||
2. 减少磁盘写入操作(更大的写缓存)
|
||||
3. 提高磁盘读取速度
|
||||
@@ -317,7 +317,7 @@ WHERE Sno IN
|
||||
|
||||
## 2.4 查询
|
||||
|
||||
### 单表查询
|
||||
### 2.4.1 单表查询
|
||||
|
||||
1. 查询多列
|
||||
|
||||
@@ -413,7 +413,7 @@ HAVING COUNT(*)>3
|
||||
|
||||
> WHERE 子句作用于基本表或视图,HAVING短语作用于组,从中选择满足条件的组,也就是分组条件。
|
||||
|
||||
### 连接查询(多表查询)
|
||||
### 2.4.2 连接查询(多表查询)
|
||||
|
||||
> 本质上是将多个表通过一些条件拼接成一张表。
|
||||
|
||||
@@ -454,7 +454,7 @@ FROM Student,SC,Cource
|
||||
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno
|
||||
```
|
||||
|
||||
### 嵌套查询
|
||||
### 2.4.3 嵌套查询
|
||||
|
||||
> 一个SELECT FROM WHERE语句成为一个查询快。将一个查询快嵌套在另一个查询块的WHERE子句或HAVING短语的条件中,称为嵌套查询。用户可以用多个简单查询构造成负责的查询,层层嵌套的结构化查询。
|
||||
|
||||
@@ -538,7 +538,7 @@ WHERE Student.Sno IN
|
||||
```
|
||||
|
||||
|
||||
### 集合查询
|
||||
### 2.4.4 集合查询
|
||||
|
||||
> 因为查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作。集合操作包括UNION、INTERSECT、EXCEPT。
|
||||
|
||||
@@ -569,7 +569,7 @@ WHERE Sage<=19
|
||||
|
||||
```
|
||||
|
||||
### 基于派生表的查询
|
||||
### 2.4.5 基于派生表的查询
|
||||
|
||||
> 子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这是子查询生成的临时派生表,成为主查询的对象。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user