This commit is contained in:
yinkanglong_lab
2021-03-09 20:51:22 +08:00
parent 99855cd76c
commit a5132d34cc
126 changed files with 9999 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
这个模板层大致又复习了一遍之前没找到的东西又发现了
在模板层中有的内奸标签API真的很有用还有很多有用的其他东西。

View File

@@ -0,0 +1,198 @@
django-admin.py全局管理工具
django-admin.py 基本命令 [参数列表]
- check
- compilemessages
- createcachetable
-
- diffsettings
- dumpdata
- flush
- inspectdb
- loaddata
- makemessages
**[migrate]:数据库命令**
- makemigrations
让django工程记录数据模型的迁移内容。知道那一部分需要迁移模型有哪些变化但是不进行操作数据库。
- migrate
真正的数据模型迁移工作,对应数据模型创建相应的数据表内容。
- showmigrations
显示数据库迁移内容
[sqldata]:数据库操作命令
- flush
清空全部数据
- dumpdata appname \> app.json
导出json格式的数据
- loaddata
导入json格式的数据
- dbshell
项目数据库的终端环境,进入数据库的命令行
- sendtestmail
- shell
**[sql]:数据库控制命令**
- sqlflush
- sqlsequencereset
- squashmigrations
**[start]:创建命令**
- startapp
创建Django的数据模型主要是MVC中的model部分。
- startproject HelloWorld
创建一个名为HelloWorld的项目
**[test]:测试命令**
- test
- testserver
manage.py项目管理工具
manage.py 基本命令 参数列表
**[auth]:用户操作命令**
- changepassword
修改用户密码
- createsuperuser
创建超级管理员
**[contenttypes]**
- remove_stale_contenttypes
**[django]**
- check
- compilemessages
- createcachetable
- dbshell
- diffsettings
- dumpdata
- flush
- inspectdb
- loaddata
- makemessages
- makemigrations
- migrate
- sendtestemail
- shell
- showmigrations
- sqlflush
- sqlmigrate
- sqlsequencereset
- squashmigrations
- startapp
- startproject
- test
- testserver
**[sessions]**
- clearsessions
**[staticfiles]**
- collectstatic
- findstatic
- runserver
启动Django自带的服务器接口对工程进行部署
python manage.py createssuperuser
用来创建超级用户通过admin管理工具实现对数据库的管理。
Django通过模型管理数据库的方法
from django.contrib import adminfrom TestModel.models import Test\# Register
your models here.admin.site.register(Test)
自定义表单
内联显示
列表显示
可以通过一大堆操作来自定义表单的格式,实现后台管理页面。
准确的说,这个东西是可以用来管理数据的,但是不能用来做前端,毕竟太丑。
也就是说如果我用Django做完了一个后台管理数据的页面最多也就新奇的说能够进行管理了还要按照Django的模式来设计前端、对数据进行渲染、然后呈现出来。
也就是说接下来要用Django做三件事情
1\. 实现后台的数据管理
2\. 写完具有相应功能的bootstrap前端
3\. 实现后端相应的交互功能。
存在的弊端:
Django是一种重量级的框架很多东西都封装到内部了可能搭建一个优美的网站十分简单但是最后如果要处理Android客户端的请求返回json格式的数据还是需要纯python的编程来实现。也就是说要跳出到框架之外。
看情况吧,如果真的需要的话,还是要学习这些新的东西。

View File

@@ -0,0 +1,51 @@
**Request对象包含的信息**
| **属性** | **描述** |
|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| path | 请求页面的全路径,不包括域名—例如, "/hello/"。 |
| method | 请求中使用的HTTP方法的字符串表示。全大写表示。例如: if request.method == 'GET': do\_something() elif request.method == 'POST': do_something\_else() |
| GET | 包含所有HTTP GET参数的类字典对象。参见QueryDict 文档。 |
| POST | 包含所有HTTP POST参数的类字典对象。参见QueryDict 文档。 服务器收到空的POST请求的情况也是有可能发生的。也就是说表单form通过HTTP POST方法提交请求但是表单中可以没有数据。因此不能使用语句if request.POST来判断是否使用HTTP POST方法应该使用if request.method == "POST" (参见本表的method属性)。 注意: POST不包括file-upload信息。参见FILES属性。 |
| REQUEST | 为了方便该属性是POST和GET属性的集合体但是有特殊性先查找POST属性然后再查找GET属性。借鉴PHP's \$_REQUEST。 例如如果GET = {"name": "john"} 和POST = {"age": '34'},则 REQUEST["name"] 的值是"john", REQUEST["age"]的值是"34". 强烈建议使用GET and POST,因为这两个属性更加显式化,写出的代码也更易理解。 |
| COOKIES | 包含所有cookies的标准Python字典对象。Keys和values都是字符串。参见第12章有关于cookies更详细的讲解。 |
| FILES | 包含所有上传文件的类字典对象。FILES中的每个Key都是\<input type="file" name="" /\>标签中name属性的值. FILES中的每个value 同时也是一个标准Python字典对象包含下面三个Keys: filename: 上传文件名,用Python字符串表示 content-type: 上传文件的Content type content: 上传文件的原始内容 注意只有在请求方法是POST并且请求页面中\<form\>有enctype="multipart/form-data"属性时FILES才拥有数据。否则FILES 是一个空字典。 |
| META | 包含所有可用HTTP头部信息的字典。 例如: CONTENT_LENGTH CONTENT_TYPE QUERY_STRING: 未解析的原始查询字符串 REMOTE_ADDR: 客户端IP地址 REMOTE_HOST: 客户端主机名 SERVER_NAME: 服务器主机名 SERVER_PORT: 服务器端口 META 中这些头加上前缀HTTP\_最为Key, 例如: HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_HOST: 客户发送的HTTP主机头信息 HTTP_REFERER: referring页 HTTP_USER_AGENT: 客户端的user-agent字符串 HTTP_X_BENDER: X-Bender头信息 |
| user | 是一个django.contrib.auth.models.User 对象,代表当前登录的用户。 如果访问用户当前没有登录user将被初始化为django.contrib.auth.models.AnonymousUser的实例。 你可以通过user的is_authenticated()方法来辨别用户是否登录: if request.user.is\_authenticated(): \# Do something for logged-in users. else: \# Do something for anonymous users. 只有激活Django中的AuthenticationMiddleware时该属性才可用 |
| session | 唯一可读写的属性代表当前会话的字典对象。只有激活Django中的session支持时该属性才可用。 参见第12章。 |
| raw_post_data | 原始HTTP POST数据未解析过。 高级处理时会有用处。 |
http.request对象中的方法
| has\_key() | 检查request.GET or request.POST中是否包含参数指定的Key。 |
|------------------|-----------------------------------------------------------------------------|
| get_full\_path() | 返回包含查询字符串的请求路径。例如, "/music/bands/the_beatles/?print=true" |
| is\_secure() | 如果请求是安全的返回True就是说发出的是HTTPS请求。 |
**QueryDict对象**
在HttpRequest对象中, GET和POST属性是django.http.QueryDict类的实例。
QueryDict类似字典的自定义类用来处理单键对应多值的情况。
QueryDict实现所有标准的词典方法。还包括一些特有的方法
| **方法** | **描述** |
|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| \_\_getitem\_\_ | 和标准字典的处理有一点不同就是如果Key对应多个Value\_\_getitem\__()返回最后一个value。 |
| \_\_setitem\_\_ | 设置参数指定key的value列表(一个Python list)。注意它只能在一个mutable QueryDict 对象上被调用(就是通过copy()产生的一个QueryDict对象的拷贝). |
| get() | 如果key对应多个valueget()返回最后一个value。 |
| update() | 参数可以是QueryDict也可以是标准字典。和标准字典的update方法不同该方法添加字典 items而不是替换它们: \>\>\> q = QueryDict('a=1') \>\>\> q = q.copy() \# to make it mutable \>\>\> q.update({'a': '2'}) \>\>\> q.getlist('a') ['1', '2'] \>\>\> q['a'] \# returns the last ['2'] |
| items() | 和标准字典的items()方法有一点不同,该方法使用单值逻辑的\_\_getitem\__(): \>\>\> q = QueryDict('a=1&a=2&a=3') \>\>\> q.items() [('a', '3')] |
| values() | 和标准字典的values()方法有一点不同,该方法使用单值逻辑的\_\_getitem\__(): |
此外, QueryDict也有一些方法如下表
| **方法** | **描述** |
|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| copy() | 返回对象的拷贝内部实现是用Python标准库的copy.deepcopy()。该拷贝是mutable(可更改的) — 就是说,可以更改该拷贝的值。 |
| getlist(key) | 返回和参数key对应的所有值作为一个Python list返回。如果key不存在则返回空list。 It's guaranteed to return a list of some sort.. |
| setlist(key,list\_) | 设置key的值为list\_ (unlike \_\_setitem\__()). |
| appendlist(key,item) | 添加item到和key关联的内部list. |
| setlistdefault(key,list) | 和setdefault有一点不同它接受list而不是单个value作为参数。 |
| lists() | 和items()有一点不同, 它会返回key的所有值作为一个list, 例如: \>\>\> q = QueryDict('a=1&a=2&a=3') \>\>\> q.lists() [('a', ['1', '2', '3'])] |
| urlencode() | 返回一个以查询字符串格式进行格式化后的字符串(e.g., "a=2&b=3&b=5"). |

View File

@@ -0,0 +1,185 @@
**模型的内容**
**from** django.db **import** models
**class** Blog(models.Model):
name **=** models.CharField(max_length**=**100)
tagline **=** models.TextField()
**def** \_\_unicode\__(self): \# \__str_\_ on Python 3
**return** self.name
**class** Author(models.Model):
name **=** models.CharField(max_length**=**50)
email **=** models.EmailField()
**def** \_\_unicode\__(self): \# \__str_\_ on Python 3
**return** self.name
**class** Entry(models.Model):
blog **=** models.ForeignKey(Blog)
headline **=** models.CharField(max_length**=**255)
body_text **=** models.TextField()
pub_date **=** models.DateField()
mod_date **=** models.DateField()
authors **=** models.ManyToManyField(Author)
n_comments **=** models.IntegerField()
n_pingbacks **=** models.IntegerField()
rating **=** models.IntegerField()
**def** \_\_unicode\__(self): \# \__str_\_ on Python 3
**return** self.headline
**使用QuerySet创建对象的方法**
类名字的静态变量objects就是与值相关的QuerySet对象
\>\>\> **from** blog.models **import** Blog
\>\>\> b **=** Blog(name**=**'Beatles Blog', tagline**=**'All the latest Beatles
news.')
\>\>\> b.save()
总之,一共有四种方法
\# 方法 1
Author.objects.create(name**=**"WeizhongTu", email**=**"tuweizhong@163.com")
\# 方法 2
twz **=** Author(name**=**"WeizhongTu", email**=**"tuweizhong@163.com")
twz.save()
\# 方法 3
twz **=** Author()
twz.name**=**"WeizhongTu"
twz.email**=**"tuweizhong@163.com"
twz.save()
\# 方法 4首先尝试获取不存在就创建可以防止重复
Author.objects.get_or\_create(name**=**"WeizhongTu",
email**=**"tuweizhong@163.com")
\# 返回值(object, True/False)
**查找对象的方法**
Person.objects.all() \# 查询所有
Person.objects.all()[:10]
切片操作获取10个人不支持负索引切片可以节约内存不支持负索引后面有相应解决办法第7条
Person.objects.get(name**=**"WeizhongTu") \# 名称为 WeizhongTu
的一条,多条会报错
get是用来获取一个对象的如果需要获取满足条件的一些人就要用到filter
Person.objects.filter(name**=**"abc") \#
等于Person.objects.filter(name__exact="abc") 名称严格等于 "abc" 的人
Person.objects.filter(name_\_iexact**=**"abc") \# 名称为 abc
但是不区分大小写,可以找到 ABC, Abc, aBC这些都符合条件
Person.objects.filter(name__contains**=**"abc") \# 名称中包含 "abc"的人
Person.objects.filter(name_\_icontains**=**"abc") \#名称中包含
"abc"且abc不区分大小写
Person.objects.filter(name__regex**=**"\^abc") \# 正则表达式查询
Person.objects.filter(name_\_iregex**=**"\^abc")\# 正则表达式不区分大小写
\# filter是找出满足条件的当然也有排除符合某条件的
Person.objects.exclude(name__contains**=**"WZ") \# 排除包含 WZ 的Person对象
Person.objects.filter(name__contains**=**"abc").exclude(age**=**23) \#
找出名称含有abc, 但是排除年龄是23岁的
**删除对象的方法**
Person.objects.filter(name__contains**=**"abc").delete() \# 删除 名称中包含
"abc"的人
如果写成
people **=** Person.objects.filter(name__contains**=**"abc")
people.delete()
效果也是一样的Django实际只执行一条 SQL 语句。
**更新某个内容的方法**
(1) 批量更新,适用于 .all() .filter() .exclude() 等后面
(危险操作,正式场合操作务必谨慎)
Person.objects.filter(name__contains**=**"abc").update(name**=**'xxx') \#
名称中包含 "abc"的人 都改成 xxx
Person.objects.all().delete() \# 删除所有 Person 记录
(2) 单个 object 更新,适合于 .get(), get_or_create(), update_or_create()
等得到的 obj和新建很类似。
twz **=** Author.objects.get(name**=**"WeizhongTu")
twz.name**=**"WeizhongTu"
twz.email**=**"tuweizhong@163.com"
twz.save() \# 最后不要忘了保存!!!
**QuerySet中可迭代对象**
(1). 如果只是检查 Entry 中是否有对象,应该用 Entry.objects.all().exists()
(2). QuerySet 支持切片 Entry.objects.all()[:10] 取出10条可以节省内存
(3). 用 len(es) 可以得到Entry的数量但是推荐用
Entry.objects.count()来查询数量后者用的是SQLSELECT COUNT(\*)
(4). list(es) 可以强行将 QuerySet 变成 列表
**QuerySet排序结果**
Author.objects.all().order\_by('name')
Author.objects.all().order_by('-name') \# 在 column name
前加一个负号,可以实现倒序
**QuerySet支持链式查询**
Author.objects.filter(name__contains**=**"WeizhongTu").filter(email**=**"tuweizhong@163.com")
Author.objects.filter(name__contains**=**"Wei").exclude(email**=**"tuweizhong@163.com")
\# 找出名称含有abc, 但是排除年龄是23岁的
Person.objects.filter(name__contains**=**"abc").exclude(age**=**23)
**QuerySet 重复的问题,使用 .distinct() 去重**

View File

@@ -0,0 +1,27 @@
与yii框架相似通过脚手架的方式直接生成对原始数据的管理并且可以通过对数据的简单控制实现管理的基础功能。
class ContactAdmin(admin.ModelAdmin):
list_display = ('name', 'age', 'email')
search_fields = ('name', 'age')
inlines = [TagInline, ]
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',), \# CSS
'fields': ('age',),
}]
)

View File

@@ -0,0 +1,98 @@
**Django settings 中 cache 默认为**
{
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
也就是默认利用**本地的内存**来当缓存,速度很快。当然可能出来内存不够用的情况,其它的一些内建可用的
Backends 有
'django.core.cache.backends.db.DatabaseCache'
'django.core.cache.backends.dummy.DummyCache'
'django.core.cache.backends.filebased.FileBasedCache'
'django.core.cache.backends.locmem.LocMemCache'
'django.core.cache.backends.memcached.MemcachedCache'
'django.core.cache.backends.memcached.PyLibMCCache'
**利用文件系统来缓存:**
CACHES **=** {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 600,
'OPTIONS': {
'MAX_ENTRIES': 1000
}
}
}
**利用数据库来缓存利用命令创建相应的表python manage.py createcachetable
cache_table_name**
CACHES **=** {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'cache_table_name',
'TIMEOUT': 600,
'OPTIONS': {
'MAX_ENTRIES': 2000
}
}
}
**一般来说我们用 Django 来搭建一个网站,要用到数据库等。**
**from** django.shortcuts **import** render
**def** index(request):
\# 读取数据库等 并渲染到网页
\# 数据库获取的结果保存到 queryset 中
**return** render(request, 'index.html', {'queryset':queryset})
**像这样每次访问都要读取数据库,一般的小网站没什么问题,当访问量非常大的时候,就会有很多次的数据库查询,肯定会造成访问速度变慢,服务器资源占用较多等问题。**
**from** django.shortcuts **import** render
**from** django.views.decorators.cache **import** cache_page
@cache_page(60 **\*** 15) \# 秒数,这里指缓存 15
分钟不直接写900是为了提高可读性
**def** index(request):
\# 读取数据库等 并渲染到网页
**return** render(request, 'index.html', {'queryset':queryset})

View File

@@ -0,0 +1,61 @@
**启用session**
**在视图中使用session**
\# 创建或修改 session
request.session[key] **=** value
\# 获取 session
request.session.get(key,default**=**None)
\# 删除 session
**del** request.session[key] \# 不存在时报错
例子让用户不能评论两次的应用原来要用session实现不重复点赞
**from** django.http **import** HttpResponse
**def** post_comment(request, new_comment):
**if** request.session.get('has_commented', False):
**return** HttpResponse("You've already commented.")
c **=** comments.Comment(comment**=**new_comment)
c.save()
request.session['has_commented'] **=** True
**return** HttpResponse('Thanks for your comment!')
**一个简化的登陆认证:**
**def** login(request):
m **=** Member.objects.get(username**=**request.POST['username'])
**if** m.password **==** request.POST['password']:
request.session['member_id'] **=** m.id
**return** HttpResponse("You're logged in.")
**else**:
**return** HttpResponse("Your username and password didn't match.")
**def** logout(request):
**try**:
**del** request.session['member_id']
**except** KeyError:
**pass**
**return** HttpResponse("You're logged out.")

View File

@@ -0,0 +1,17 @@
使用GET方法接受表单
\<form action="/search" method="get"\> \<input type="text" name="q"\> \<input
type="submit" value="搜索"\>\</form\>
\# 接收请求数据def search(request): request.encoding='utf-8' if 'q' in
request.GET: message = '你搜索的内容为: ' + request.GET['q'] else: message =
'你提交了空表单' return HttpResponse(message)
使用post方法对表单进行操作
\<form action="/search-post" method="post"\> {% csrf_token %} \<input
type="text" name="q"\> \<input type="submit" value="Submit"\> \</form\> \<p\>{{
rlt }}\</p\>
\# 接收POST请求数据def search_post(request): ctx ={} if request.POST: ctx['rlt']
= request.POST['q'] return render(request, "post.html", ctx)

View File

@@ -0,0 +1,64 @@
MVC模型中model部分提供对数据库的操作支持。
**配置文件settings.py**
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', \# 或者使用
mysql.connector.django 'NAME': 'test', 'USER': 'test', 'PASSWORD': 'test123',
'HOST':'localhost', 'PORT':'3306', } }
**django-admin.py startapp TestModel**
创建模型,目录结构如下
HelloWorld\|-- TestModel\| \|-- \__init_\_.py\| \|-- admin.py
在管理界面中修改应用程序的模型\| \|-- models.py 存储所有的应用程序的模型\| \|--
tests.py 单元测试\| \|-- views.p 应用程序的视图
**对models.py的理解**
\# models.pyfrom django.db import modelsclass Test(models.Model): name =
models.CharField(max_length=20)
是模型定义的地方,提供了与数据库对应的类方法
**配置INSTALLED_APPS这一项**
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.staticfiles', 'TestModel', \#
添加此项)
**实现数据库迁移工作**
- **python manage.py makemigrations TestModel**
创建特定的.py
文件用来让Django记录模型的特点和对数据库的操作但实际上没有操作数据库。
- **python manage.py migrate TestModel**
将模型和数据库链接。对应模型,在数据库中创建指定的表格。如果已经建好数据库,应该不用执这两个命令。
数据库的相关操作def testdb(request): \# 初始化 response = "" response1 = "" \#
通过objects这个模型管理器的all()获得所有数据行相当于SQL中的SELECT \* FROM list
= Test.objects.all() \# filter相当于SQL中的WHERE可设置条件过滤结果 response2 =
Test.objects.filter(id=1) \# 获取单个对象 response3 = Test.objects.get(id=1) \#
限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
Test.objects.order_by('name')[0:2] \#数据排序 Test.objects.order_by("id") \#
上面的方法可以连锁使用 Test.objects.filter(name="runoob").order_by("id") \#
输出所有数据 for var in list: response1 += var.name + " " response = response1
return HttpResponse("\<p\>" + response + "\</p\>")
**Python可以使用自带的shell实现数据库的操作真他妈的简洁优雅**
- 数据库存储
p = Person(name = "WZ", age = 23)
p.save()
- all()用来获取对象列表
- get()用来获取一个对象
- filter()用来获取满足条件的一系列对象允许使用Python这则表达式进行查询。

View File

@@ -0,0 +1,117 @@
template模板的具体使用
创建模板,目录结构如下:
\|-- HelloWorld\|-- manage.py \`-- templates \`-- hello.html
修改配置文件当中TEMPLATES的基础路径
...TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR+"/templates",], \# 修改位置 'APP_DIRS': True, 'OPTIONS': {
'context_processors': [ 'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', ], }, },]...
使用模板如下(view.py)
使用render函数+数据+渲染内容实现结果输出
from django.shortcuts import renderdef hello(request): context = {}
context['hello'] = 'Hello World!' return render(request, 'hello.html', context)
Django templates模板标签
**if-elif-endif标签**
{% if condition %}
display 1
{% elif condition2 %}
display 2
{% else %}
display 3
{% endif %}
**for-endfor标签**
{% for athlete in athlete_list %}
\<li\>{{ athlete.name}}\</li\>
{% endfor %}
循环中的默认变量
{**%** **for** item **in** List **%**}
{{ item }}{**%** **if** **not** forloop.last **%**},{**%** endif **%**}
{**%** endfor **%**}
\<**ul**\>
{% for athlete in athlete_list %}
\<**li**\>{{ athlete.name }}\</**li**\>
{% empty %}
\<**li**\>抱歉,列表为空\</**li**\>
{% endfor %}
\</**ul**\>
| 变量 | 描述 |
|-------------------------|-------------------------------------------------------|
| **forloop.counter** | 索引从 1 开始算 |
| **forloop.counter0** | 索引从 0 开始算 |
| **forloop.revcounter** | 索引从最大长度到 1 |
| **forloop.revcounter0** | 索引从最大长度到 0 |
| **forloop.first** | 当遍历的元素为第一项时为真 |
| **forloop.last** | 当遍历的元素为最后一项时为真 |
| **forloop.parentloop** | 用在嵌套的 for 循环中, 获取上一层 for 循环的 forloop |
**ifequal/ifnotequal 标签**
{% ifequal user currentuser %}
\<h1\>Welcome!\</h1\>
{% endifequal %}
**注释标签**
{\# 这是一个注释 \#}
**过滤器标签**
lower是一个过滤管道允许被套接
{{ name\|lower }}
常见的过滤管道
{{...\|first\|upper\|lower\|truncatewords:"30"\|date:"F j ,Y"}}
**include标签**
{% include "nav.html" %}
Django模板的继承
模板通过继承实现代码的复用,下面是父文件
\<body\> \<h1\>Hello World!\</h1\> \<p\>菜鸟教程 Django 测试。\</p\> {% block
mainbody %} \<p\>original\</p\>{% endblock %}\</body\>
下面是子文件可以替换block部分
{% extends "base.html" %} {% block mainbody %}\<p\>继承了 base.html 文件\</p\>{%
endblock %}

View File

@@ -0,0 +1,69 @@
Django工程创建
**django-admin.py startproject HelloWorld**
创建Django项目。其目录结构为\|-- HelloWorld //项目的容器内有view控制中心\|
\|-- \__init_\_.py //包声明文件\| \|-- settings.py //该Django项目的配置文件\|
\|-- urls.py //Django项目的URL声明\| \`-- wsgi.py
//该Django项目的WSGI兼容的web服务器入口python内置服务器程序 \`-- manage.py
//与项目相关的命令行工具实现与Django的交互。
**python manage.py runserver 0.0.0.0:8000**
启动服务器,并将该项目部署到服务器当中。
**HelloWorld/view.py**
from django.http import HttpResponsedef hello(request): return
HttpResponse("Hello world ! ")
view文件的标准函数。负责接收request并将request进行处理返回response提供给用户。
**Helloworld/urls.py**
from django.conf.urls import urlfrom . import viewurlpatterns = [ url(r'\^\$',
view.hello),]
urls文件的标准格式哦调羹说配置URL和view方法之间的对应关系建立URL和view方法之间的映射。其中urlpatterns变量的配置函数如下
url(regex, view, kwargs, name)
regex: 正则表达式匹配相应的url
view: view方法用来吹与正则表达式匹配的url
kwargsview使用的字典类型的参数。
name用来反向获取URL
**关于url name的详细说明。**
- 为了在视图渲染过程中获取真正的请求网址。大致理解了一些url可以通过正则表达式匹配到urlpattern中的一个函数但是有的时候这个网址会变化导致原来的匹配不再生效。那么就提供了一种通过名字来匹配具体url的方式。当网址变化时名字已久能帮助原来的url定位到新的网址。
- 在原网址链接的地方使用名字+参数的方式可以自动渲染成最新的url格式。
原来的匹配项
url(r'\^add/(\\d+)/(\\d+)/\$', calc\_views.add2, name**=**'add2'),
现在的匹配项
url(r'\^new_add/(\\d+)/(\\d+)/\$', calc\_views.add2, name**=**'add2'),
原来的链接将不能访问
\<**a** href="/add/4/5/"\>link\</**a**\>
但是通过名字的链接会自动渲染成当前的url匹配模式
\<**a** href="{% url 'add2' 4 5 %}"\>link\</**a**\>
渲染成→\<**a** href="/add/4/5/"\>link\</**a**\>
渲染成→\<**a** href="/new_add/4/5/"\>link\</**a**\>
具体渲染的方式为下面的方式会生成对应的urlpattern。
**from** django.core.urlresolvers **import** reverse
reverse('add2', args**=**(a, b))

View File

@@ -0,0 +1,124 @@
其中有一节专门讲了File对象如何上传然而上一次为这个文件上传苦恼了很久。
**重新复习了两个关键对象**
**HttpRequest对象**
.scheme 表示请求的方案http或者https
.body
原始HTTP请求的正文。包括GET请求的参数POST请求的表单媒体对象的二进制文件。
.path 表示请求页面的完整路径,不包含域名,可以用来点赞或者喜欢之后刷新原来的网页
.method HTTP请求的方法GET或者POST
.encoding 请求的编码
.GET 一个字典对象包含HTTP GET的参数
.POST 一个类字典对象,包含了表单数据的请求。
.FILES 一个字段对象,包含所上传的文件。
.COOKIES 标准的python字典包含所有的cookie。键和值都是字符串
.META 一个python字典包含HTTP头部信息。
.user 一个用户对象。
.session 一个可以读写的session字典对象。
方法:
get\_host()
获取主机名**127.0.0.1:8000**
get_full\_path()
返回path和查询字符串**/music/bands/the_beatles/?print=true**
**QueryDict对象**
首先实现了字典所有的标准方法。
\_\_getitem\__(key)
\_\_setitem\__(key,value)
\__contains__(key)
get(key,default)不存在时返回默认值
setdefault(key,default)
update(other_dict),将新的值添加到后边
items()返回字典的一个列表[('a', '3')]
iteritems()
iterlists()
values() 返回值的一个列表['3']
itervalues() 返回一个迭代器
copy()调用python库中的deepcopy()进行神复制
getlist(key,default)以列表返回所有请求的键
appendlist(key,item)
setlistdefault(key,default\_list)
lists()
pop(key)弹出
popitem()随机弹出
dict()返回dict对象
**httpResponse对象**
.content 一个字节字符
.charset response编码的字符串
.status_code HTTP相应状态码
.reason_phrase HTTP原因短语
.streaming 总是false
.closed 响应是否关闭
.\_\_setitem\__(header,value)设定报文首部。
.\_\_delitem\__(header)
.\_\_getitem\__(header)
.has\_header(header)
.set\_cookie()
.set_signed_cookie() 设置cookie并用秘钥签名
.delete_cookie() 删除cookie
.write()
.flush()
.tell()
**其子类包括以下**
HttpResponseRedirect对象
HttpResponseNotModified
HttpResponsePermanentRedirect

View File

@@ -0,0 +1,162 @@
**基本原则说明:**
- Django会一次匹配列表中的每个URL模式在遇到第一个请求的URL相匹配的模式时停下来
- 分组传参包括以下内容:
- 一个HttpRequest实例。
- 如果正则表达式是无名组,那么正则表达式所匹配的内容将作为位置参数提供给视图。
- 如果正则表达式是命名组,那么正则表达式所匹配的内容将作为关键参数提供给视图。
- 对于GET、POST请求本身的参数不进行匹配。作为扩展参数kwargs提供给视图。
- 如果请求的URL没有匹配到任何一个正则表达式或者匹配过程中抛出异常会进行相应的错误处理。
分组参数
关键参数
**匹配分组算法说明:**
\> 分组对应参数,是如何传递参数的过程;匹配分组算法,是如何匹配字符串的过程。
- 如果有命名参数,则使用命名参数,忽略非命名参数。
- 否则,将以位置参数传递所有的非命名参数。
- 所有的匹配结果都是字符串
能够通过url函数额外传递多个参数。
终于他妈的明白这种关键参数和位置参数的意思了:
关键参数是为了匹配具体的字符串,位置参数是按照先后位置匹配字符串。他妈的,果然看不天不如写两行试试。谨记,这里的匹配原则。和之前的分组传递参数原则。如此简单,是自己最近变愚钝了吗,好久没做数学题了吗,思路一点都不够灵活,而且好像由于电子屏幕的原因,记忆力下降好快。
**URL反向解析说明**
- 在视图中使用标签进行反向解析
**\<a** href="**{%** **url** 'news-year-archive' yearvar **%}**"**\>{{** yearvar
**}}** Archive**\</a\>**
- 在代码中使用reverse函数进行反向解析
reverse('news-year-archive', args**=**(year,))
**模板标签URL反向解析**
- 通过url标签、名称、位置参数直接反转
**{%** **url** 'some-url-name' v1 v2 **%}**
- 通过url标签、名称、关键参数直接反转。没有成功验证过这种关键参数长什么模样。
**{%** **url** 'some-url-name' arg1**=**v1 arg2**=**v2 **%}**
\> 位置参数和关键参数不能混用
**1,定义:**
> 随着功能的增加会出现更多的视图,可能之前配置的正则表达式不够准确,于是就要修改正则表达式,但是正则表达式一旦修改了,之前所有对应的超链接都要修改,真是一件麻烦的事情,而且可能还会漏掉一些超链接忘记修改,有办法让链接根据正则表达式动态生成吗?
> 就是用反向解析的办法。
**2,应用范围:**
- 模板中的超链接
- 视图中的重定向
**3,使用方法:**
- 定义url时需要为include定义namespace属性为url定义name属性
- 使用时在模板中使用url标签在视图中使用reverse函数根据正则表达式动态生成地址减轻后期维护成本。
**4,模板中超链接步骤:**
1在项目urls.py中为include定义namespace属性。
> url(r\^,include(booktest.urls,namespace=booktest)),
2在应用的urls.py中为url定义name属性并修改为fan2。
> url(r\^fan2/\$, views.fan2,name=fan2),
3在模板中使用url标签做超链接此处为templates/booktest/fan1.html文件。
\<html\>\<head\> \<title\>反向解析\</title\>\</head\>\<body\>普通链接:\<a
href="/fan2/"\>普通fan2\</a\>\<hr\>反向解析:\<a href="{%url
'booktest:fan2'%}"\>反向解析fan2\</a\>\</body\>\</html\>
4回到浏览器中后退刷新查看源文件两个链接地址一样。
![630170720665.png](media/dce0ba0294ba5eabe258c5e8e57a3054.png)
这里写图片描述
5在应用的urls.py中将fan2修改为fan_show。
> url(r\^fan_show/\$, views.fan2,name=fan2),
6回到浏览器中刷新查看源文件两个链接地址不一样。
![630170353712.png](media/df40d5376061534624358d06423cfa57.png)
这里写图片描述
**4,视图中的重定向:**
from django.shortcuts import redirect from django.core.urlresolvers import
reverse return redirect(reverse('booktest:fan2'))
**5,反向解析中URL的参数**
**位置参数**
1在booktest/urls.py中修改fan2如下
> url(r\^fan(\\d+)\_(\\d+)/\$, views.fan2,name=fan2),
2修改templates/booktest/fan1.html文件如下
\<html\>\<head\> \<title\>反向解析\</title\>\</head\>\<body\>普通链接:\<a
href="/fan2_3/"\>fan2\</a\>\<hr\>反向解析:\<a href="{%url 'booktest:fan2' 2
3%}"\>fan2\</a\>\</body\>\</html\>
3回到浏览器中刷新查看源文件如下图
![630165632134.png](media/017b5bc5cc1c5658c2e4b0d2c60d6a66.png)
这里写图片描述
- 使用重定向传递位置参数格式如下:
return redirect(reverse(booktest:fan, args=(2,3)))
**关键字参数**
1在booktest/urls.py中修改fan2如下
url(r'\^fan(?P\<id\>\\d+)\_(?P\<age\>\\d+)/\$', views.fan2,name='fan2'),
- 1
2修改templates/booktest/fan1.html文件如下
\<html\>\<head\> \<title\>反向解析\</title\>\</head\>\<body\>普通链接:\<a
href="/fan100_18/"\>fan2\</a\>\<hr\>反向解析:\<a href="{%url 'booktest:fan2'
id=100 age=18%}"\>fan2\</a\>\</body\>\</html\>
3回到浏览器中刷新查看源文件如下图
![630165958760.png](media/31dee5e6af1761fcf709bd964dbae2e6.png)
这里写图片描述
- 使用重定向传递关键字参数格式如下:
return redirect(reverse(booktest:fan2, kwargs={id:110,age:26}))
真他妈的日了够了,老子居然又因为拼写错误浪费了这么多时间。

View File

@@ -0,0 +1,58 @@
**http请求处理的MVC结构**
![clipboard.png](media/9670ce8128fc0e85e25497e4b5fa4d1c.png)
**HTTP处理的中间件结构**
![clipboard.png](media/1ea5844cdeb119cea0014629f5a98677.png)
![clipboard.png](media/d7386f1dbbc74996c289b2a429824bea.png)
记住几个重要的预处理函数
**process\_request(self, request)**
request预处理函数
在**Django接收到request**之后但仍未解析URL以确定应当运行的view之前。调用
返回 NoneDjango将继续处理这个request执行后续的中间件
然后调用相应的view“我对继续处理这个request没意见”
或者返回 HttpResponse 对象Django
将不再执行任何其它的中间件(无视其种类)以及相应的view。 Django将立即返回该
HttpResponse“我不想其他代码处理这个request我要提早返回” .
process\_view(self, request, callback, callback_args, callback_kwargs)
view预处理函数
在Django执行完request预处理函数并确定待执行的view之后但在view函数实际执行之前。
process\_response(self, request, response)
Response后处理函数
在\*\*\*\*Django\*\*\*\*执行view\*\*\*\*函数\*\*\*\*并生成\*\*\*\*response\*\*\*\*之后
该处理器能修改response\*\*\*\*的内容
**记住一些琐碎的知识**
- 一个工程可以有很多model一个model就代表一个一个app他有自己的数据关联到相应的数据库和自己的控制器视图views用来实现对model的操作和访问。现在的疑问可能就是每一部分是负责做什么的到底该怎样组织整个工程。
- url支持的各种匹配。可以通过正则表达式来实现不同url的配置。request中的对GET与POST对象都是queryDict的实例是普通Dict的扩展兼容了普通Dict的一些基本方法。
**django的组成结构**
管理工具Management主要通过管理工具的命令来实现对整个工程的控制。一整套内置的创建站点、迁移数据、维护静态文件的命令。
模型model提供数据访问的接口和模块。
视图view封装了HTTP request和response的一系列操作和数据流函数、类视图
模板template一整套Django自己的页面渲染语言。若干内置的tags和filters
表单form通过内置的数据类型控制表单和控件生成HTML表单。已经差不多了
管理站Admin通过生命管理Model快速生成后台数据管理网站。

View File

@@ -0,0 +1,6 @@
render 使用模板进行渲染
redirect
重定向到一个新的url也就是说我当前没有渲染的视图我交给另外一个动作来处理我提供动作必要的参数。所以传递参数到视图的过程绝对不应该用redirect而是render。
redirect有多种形式。可以是绝对路径、相对路径、动作视图名称 + 必要的参数

View File

@@ -0,0 +1,754 @@
这个是当前最终要的一部分知识,因为接下来的工作包括太多的数据库操作了,必须得详细了解一下。
\---------------------------------------------------------------------------------------------------------------
关于模型的说明
**字段选项**
定义字段过程中对字段的性质进行控制
- null
- blank
- choices
- db_column
- db_index
- db_tablespace
- default
- auto_to_now
- error_messages
- help_text
- primary_key主键
- unique唯一性
- unique_for_date
- unique_for_month
- unique_for_year
- verbose_name
- 验证器
- 注册和获取查询
**字段类型**
定义字段的类型
- AutoField自增字段
- BigIntegerField
- 二进制字段
- BooleanField
- For
- CommaSeparatedIntegerField
- rendering
- DateField
- DecimalField
- DurationField
- EmailField
- FileField
FileField和FieldFile
- FilePathField
- FloatField
- forms
- IntegerField
- IPAddressField
- GenericIPAddressField
- NullBooleanField
- PositiveIntegerField
- PositiveSmallIntegerField
- SlugField
- SmallIntegerField
- TextField文本域
- TimeField
- URLField
- UUIDField
**字段关系**
- ForeignField
- ManyToManyField
- OneToOneField
\--------------------------------------------------------------------------------------------------------------------------------
关于对象的操作
**创建对象**
直接创建
b **=** Blog(name**=**'Beatles Blog', tagline**=**'All the latest Beatles
news.')
可以使用objects管理器的create方法
joe **=** Author**.**objects**.**create(name**=**"Joe")
**保存对象**
可以保存对象的更新,也可以添加新的对象。
save()
**获取对象**
管理器方法执行sql语句
有很多方法QuerySet API单独说明
**---------------------------------------------------------**
**查询集求值方法**
因为Django采取了惰性查询的方法只要不是用就不会执行查询语句求值。以下方法会导致sql语句被执行。
**迭代**
**切片step参数为true**
**序列化缓存**
**repr()**
**len()**返回查询集的长度并对查询集进行求值COUNT 函数是不求值得)
**list()**对查询集进行强制求值从queryset变为普通列表
entry_list **=** list(Entry**.**objects**.**all())
**bool()**判断查询集是否存在
**if** Entry**.**objects**.**filter(headline**=**"Test"): **print**("There is at
least one Entry with the headline Test")
**基本查询**
Entry**.**objects**.**all()
返回包含数据库中所有对象的一个**查询集**。
**filter(\*\*kwargs)**
返回一个新的**查询集**,它包含满足查询参数的对象。
**exclude(\*\*kwargs)**
返回一个新的**查询集**,它包含不满足查询参数的对象。
Entry**.**objects**.**get(**\*\*kwargs**)
直接返回该对象(返回查询到的第一个对象)
**extra**
**extra(**select=None**,** where=None**,** params=None**,** tables=None**,**
order_by=None**,**
select_params=None**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.extra)
有些情况下Django的查询语法难以简单的表达复杂的 **WHERE** 子句,对于这种情况,
Django 提供了 **extra()** **QuerySet** 修改机制 — 它能在
**QuerySet**生成的SQL从句中注入新子句
功能太过强大应该用不到
**raw**
**raw(**raw_query**,** params=None**,** translations=None**)**
接收一个原始的SQL 查询,执行它并返回一个**django.db.models.query.RawQuerySet**
实例。这个**RawQuerySet** 实例可以迭代以提供实例对象,就像普通的**QuerySet**
一样。
**不返回查询集的查询**
**get**
**get(**\*\*kwargs**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.get)
返回按照查询参数匹配到的对象,参数的格式应该符合 [Field
lookups](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#id4)的要求.
- 如果匹配到的对象个数不只一个的话,**get()**
将会触发[**MultipleObjectsReturned**](http://python.usyiyi.cn/documents/django_182/ref/exceptions.html#django.core.exceptions.MultipleObjectsReturned)
异常.
[**MultipleObjectsReturned**](http://python.usyiyi.cn/documents/django_182/ref/exceptions.html#django.core.exceptions.MultipleObjectsReturned)
异常是模型类的属性.
- 如果根据给出的参数匹配不到对象的话,**get()**
将触发[**DoesNotExist**](http://python.usyiyi.cn/documents/django_182/ref/models/instances.html#django.db.models.Model.DoesNotExist)
异常. 这个异常是模型类的属性.
Entry**.**objects**.**get(id**=**'foo') *\# raises Entry.DoesNotExist*
> 异常处理
> **from** **django.core.exceptions** **import** ObjectDoesNotExist **try**: e
> **=** Entry**.**objects**.**get(id**=**3) b **=**
> Blog**.**objects**.**get(id**=**1)**except** ObjectDoesNotExist:
> **print**("Either the entry or blog doesn't exist.")
**create**
**create(**\*\*kwargs**)**
一个在一步操作中同时创建对象并且保存的便捷方法.
p **=** Person**.**objects**.**create(first_name**=**"Bruce",
last_name**=**"Springsteen")
> 和:
> p **=** Person(first_name**=**"Bruce", last_name**=**"Springsteen")
> p**.**save(force_insert**=**True)
> 是等同的.
**get_or_create**
**get_or\_create(**defaults=None**,**
\*\*kwargs**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.get_or_create)
一个通过给出的**kwargs**
来查询对象的便捷方法(如果你的模型中的所有字段都有默认值,可以为空),需要的话创建一个对象。
> **try**: obj **=** Person**.**objects**.**get(first_name**=**'John',
> last_name**=**'Lennon')**except** Person**.**DoesNotExist: obj **=**
> Person(first_name**=**'John', last_name**=**'Lennon',
> birthday**=**date(1940, 10, 9)) obj**.**save()
> 等同于
> obj, created **=**
> Person**.**objects**.**get_or\_create(first_name**=**'John',
> last_name**=**'Lennon',defaults**=**{'birthday': date(1940, 10, 9)})
**update_or_create**
**update_or\_create(**defaults=None**,** \*\*kwargs**)**
一个通过给出的**kwargs** 来更新对象的便捷方法,
如果需要的话创建一个新的对象。**defaults** 是一个由 (field, value)
对组成的字典,用于更新对象。
**try**: obj **=** Person**.**objects**.**get(first_name**=**'John',
last_name**=**'Lennon') **for** key, value **in**
updated_values**.**iteritems(): setattr(obj, key, value)
obj**.**save()**except** Person**.**DoesNotExist:
updated_values**.**update({'first_name': 'John', 'last_name': 'Lennon'}) obj
**=** Person(**\*\***updated_values) obj**.**save()
等同于
obj, created **=** Person**.**objects**.**update\_or_create(
first_name**=**'John', last_name**=**'Lennon', defaults**=**updated_values)
**bulk_create**
**bulk\_create(**objs**,** batch_size=None**)**
此方法以有效的方式通常只有1个查询无论有多少对象将提供的对象列表插入到数据库中
**\>\>\>** Entry**.**objects**.**bulk\_create([**...**
Entry(headline**=**"Django 1.0 Released"),**...** Entry(headline**=**"Django
1.1 Announced"),**...** Entry(headline**=**"Breaking: Django is
awesome")**...** ])
**count**
**count()**
返回在数据库中对应的 **QuerySet**.对象的个数。 **count()** 永远不会引发异常。
例:
*\# Returns the total number of entries in the
database.*Entry**.**objects**.**count()*\# Returns the number of entries whose
headline contains
'Lennon'*Entry**.**objects**.**filter(headline__contains**=**'Lennon')**.**count()
**iterator**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#iterator)
**iterator()**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.iterator)
评估**QuerySet**(通过执行查询),并返回一个迭代器
**first**
**first()**
返回结果集的第一个对象, 当没有找到时返回**None**.如果 **QuerySet**
没有设置排序,则将会自动按主键进行排序
例:
p **=** Article**.**objects**.**order\_by('title', 'pub_date')**.**first()
笔记:**first()** 是一个简便方法 下面这个例子和上面的代码效果是一样
**try**: p **=** Article**.**objects**.**order\_by('title',
'pub_date')[0]**except** **IndexError**: p **=** None
**aggregate聚合查询**
**aggregate(**\*args**,** \*\*kwargs**)**
返回一个字典,包含根据**QuerySet**
计算得到的聚合值(平均数、和等等)。**aggregate()**
的每个参数指定返回的字典中将要包含的值。
**\>\>\> from** **django.db.models** **import** Count **\>\>\>** q **=**
Blog**.**objects**.**aggregate(Count('entry')){'entry__count': 16}
通过使用关键字参数来指定聚合函数,你可以控制返回的聚合的值的名称:
**\>\>\>** q **=**
Blog**.**objects**.**aggregate(number_of_entries**=**Count('entry')){'number_of_entries':
16}
**exists**
**exists()**
如果[**QuerySet**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet)
包含任何结果,则返回**True**,否则返回**False**。
entry **=** Entry**.**objects**.**get(pk**=**123)**if**
some_queryset**.**filter(pk**=**entry**.**pk)**.**exists(): **print**("Entry
contained in queryset")
**update**
**update(**\*\*kwargs**)**
对指定的字段执行SQL更新查询并返回匹配的行数如果某些行已具有新值则可能不等于已更新的行数
例如要对2010年发布的所有博客条目启用评论您可以执行以下操作
**\>\>\>**
Entry**.**objects**.**filter(pub_date__year**=**2010)**.**update(comments_on**=**False)
**delete**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#delete)
**delete()**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.delete)
对[**QuerySet**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet)中的所有行执行SQL删除查询。立即应用**delete()**。您不能在[**QuerySet**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet)上调用**delete()**,该查询已采取切片或以其他方式无法过滤。
要删除特定博客中的所有条目:
**\>\>\>** b **=** Blog**.**objects**.**get(pk**=**1)\# Delete all the entries
belonging to this Blog.**\>\>\>**
Entry**.**objects**.**filter(blog**=**b)**.**delete()
**字段查询**
查询的关键字参数的基本形式是**field__lookuptype=value**。字段查询是指如何指定SQL
**WHERE**子句的内容.
它们通过**查询集**的[**filter()**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.filter),
[**exclude()**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.exclude)
and
[**get()**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.get)的关键字参数指定.
**exact**
精确匹配。如果为比较提供的值为**None**它将被解释为SQL **NULL**
Entry**.**objects**.**get(id__exact**=**14)
Entry**.**objects**.**get(id__exact**=**None)
**iexact**
不区分大小写的精确匹配
Blog**.**objects**.**get(name_\_iexact**=**'beatles blog')
Blog**.**objects**.**get(name_\_iexact**=**None)
**contains**
区分大小写的包含例子。
Entry**.**objects**.**get(headline__contains**=**'Lennon')
**icontains**
不区分大小写的包含
Entry**.**objects**.**get(headline_\_icontains**=**'Lennon')
**in**
在给定的列表。
Entry**.**objects**.**filter(id__in**=**[1, 3, 4])
在一次查询的结果集合中进行查询
inner_qs **=**
Blog**.**objects**.**filter(name__contains**=**'Ch')**.**values('name') entries
**=** Entry**.**objects**.**filter(blog__name__in**=**inner_qs)
**gt**
大于
Entry**.**objects**.**filter(id_\_gt**=**4)
**gte**
大于或等于
**lt**
小于
**lte**
小于或等于
**startswith**
区分大小写,开始位置匹配
Entry**.**objects**.**filter(headline_\_startswith**=**'Will')
**istartswith**
不区分大小写,开始位置匹配
Entry**.**objects**.**filter(headline_\_istartswith**=**'will')
**endswith**
区分大小写。
**iendswith**
不区分大小写。
**range**
范围测试(包含于之中,在时间相关的查询中尤为重要,如果你要获取这一周的内容的话,肯定要用到这一周的内容)。
**import** **datetime** start_date **=** datetime**.**date(2005, 1, 1) end_date
**=** datetime**.**date(2005, 3, 31)
Entry**.**objects**.**filter(pub_date__range**=**(start_date, end_date))
部分日期的关键字参数
year month day weekday hour minute second
**isnull**
值为 **True****False**
Entry**.**objects**.**filter(pub_date_\_isnull**=**True)
正则表达式
**regex**
区分大小写的正则表达式匹配。
Entry**.**objects**.**get(title__regex**=**r'\^(An?\|The) +')
**iregex**
不区分大小写的正则表达式匹配。
Entry**.**objects**.**get(title_\_iregex**=**r'\^(an?\|the) +')
**聚合函数**
在**QuerySet** 为空时,聚合函数函数将返回**None**。 例如,如果**QuerySet**
中没有记录,**Sum** 聚合函数将返回**None** 而不是**0**。**Count**
是一个例外,如果**QuerySet** 为空,它将返回**0**。
聚合函数的参数有以下三个
**expression**
引用模型字段的一个字符串,或者一个[查询表达式](http://python.usyiyi.cn/documents/django_182/ref/models/expressions.html)。
**output_field**
用来表示返回值的[模型字段](http://python.usyiyi.cn/documents/django_182/ref/models/fields.html),它是一个可选的参数。
**\*\*extra**
这些关键字参数可以给聚合函数生成的SQL 提供额外的信息。
具体的聚合函数:
**avg**
class **Avg(**expression**,** output_field=None**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Avg)
返回给定expression 的平均值其中expression 必须为数值。
- 默认的别名:**\<field\>__avg**
- 返回类型:**float**
**Count**
class **Count(**expression**,** distinct=False**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Count)
返回与expression 相关的对象的个数。
- 默认的别名:**\<field\>__count**
- 返回类型:**int**
有一个可选的参数:
> **distinct**
> 如果**distinct=True**Count 将只计算唯一的实例。它等同于**COUNT(DISTINCT
> \<field\>)** SQL 语句。默认值为**False**。
**Max**
class **Max(**expression**,** output_field=None**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Max)
返回expression 的最大值。
- 默认的别名:**\<field\>__max**
- 返回类型:与输入字段的类型相同,如果提供则为 **output_field** 类型
**Min**
class **Min(**expression**,** output_field=None**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Min)
返回expression 的最小值。
- 默认的别名:**\<field\>__min**
- 返回的类型:与输入字段的类型相同,如果提供则为 **output_field** 类型
**StdDev**
class **StdDev(**expression**,** sample=False**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.StdDev)
返回expression 的标准差。
- 默认的别名:**\<field\>_\_stddev**
- 返回类型:**float**
有一个可选的参数:
> **sample**
> 默认情况下,**StdDev**
> 返回群体的标准差。但是,如果**sample=True**,返回的值将是样本的标准差。
**Sum**
class **Sum(**expression**,** output_field=None**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Sum)
计算expression 的所有值的和。
- 默认的别名:**\<field\>__sum**
- 返回类型:与输入的字段相同,如果提供则为**output_field** 的类型
**Variance**
class **Variance(**expression**,** sample=False**,**
\*\*extra**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.Variance)
返回expression 的方差。
- 默认的别名:**\<field\>__variance**
- 返回的类型:**float**
有一个可选的参数:
> **sample**
> 默认情况下,**Variance**
> 返回群体的方差。但是,如果**sample=True**,返回的值将是样本的方差。
**链式过滤**
查询集的筛选结果本身还是查询集,所以可以将筛选语句链接在一起。像这样:
**\>\>\>** Entry**.**objects**.**filter(**...**
headline_\_startswith**=**'What'**...** )**.**exclude(**...**
pub_date_\_gte**=**datetime**.**date**.**today()**...** )**.**filter(**...**
pub_date_\_gte**=**datetime(2005, 1, 30)**...** )
**限制查询**
Entry**.**objects**.**all()[:5]
限制查询集记录的条数
**orderby**
Entry**.**objects**.**order\_by('headline')[0]
对查询集进行排序
Entry**.**objects**.**order\_by('blog__name')
通过关联字段进行排序
Entry**.**objects**.**order\_by(Coalesce('summary', 'headline')**.**desc())
通过Coalesce函数指定多个字段通过desc()和asc()函数制定排序方向
**reverse()**
**reverse()** 方法反向排序QuerySet 中返回的元素。
**distinct([**\*fields**]**
返回一个在SQL 查询中使用**SELECT DISTINCT**
的新**QuerySet**。它将去除查询结果中重复的行。
**values(**\*fields**)**
返回一个**ValuesQuerySet** —— **QuerySet**
的一个子类,迭代时返回**字典SET**而不是模型实例**对象SET**。
每个字典表示一个对象,键对应于模型对象的属性名称。
**values\_list(**\*fields**,**
flat=False**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.values_list)
与**values()**
类似,只是在迭代时返回的是**元组SET**而不是**字典SET**。每个元组包含传递给**values_list()**
调用的字段的值 —— 所以第一个元素为第一个字段,以此类推。
**关联查询**
通过关联对象的字段进行查询。可以跨越任意深度。
获取所有**Blog** 的**name** 为**'Beatles Blog'** 的**Entry** 对象:
Entry**.**objects**.**filter(blog__name**=**'Beatles Blog')
对于关联关系也可以反向查询
获取所有的**Blog** 对象,它们至少有一个**Entry** 的**headline** 包含**'Lennon'**
Blog**.**objects**.**filter(entry__headline__contains**=**'Lennon')
**select_related**
**select_related(**\*fields**)**
返回一个**QuerySet**,当执行它的查询时它沿着外键关系查询关联的对象的数据。它会生成一个复杂的查询并引起性能的损耗,但是在以后使用外键关系时将不需要数据库查询。
下面的例子解释了普通查询和**select\_related()**
查询的区别。下面是一个标准的查询:
*\# Hits the database.* e **=** Entry**.**objects**.**get(id**=**5)*\# Hits the
database again to get the related Blog object.* b **=** e**.**blog
下面是一个**select_related** 查询:
*\# Hits the database.* e **=**
Entry**.**objects**.**select\_related('blog')**.**get(id**=**5)*\# Doesn't hit
the database, because e.blog has been prepopulated\# in the previous query.* b
**=** e**.**blog
**prefetch_related¶**
**prefetch_related(**\*lookups**)**[**¶**](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet.prefetch_related)
返回**QuerySet**,它将在单个批处理中自动检索每个指定查找的相关对象。
**\>\>\>** Pizza**.**objects**.**all()["Hawaiian (ham, pineapple)", "Seafood
(prawns, smoked salmon)"...
问题是每次**Pizza .\_\_ str
\__()**要求**self.toppings.all()**它必须查询数据库,因此**Pizza.objects
.all()**将在Pizza **QuerySet**中的**每个**项目的Toppings表上运行查询。
我们可以使用**prefetch_related**减少为只有两个查询:
**\>\>\>** Pizza**.**objects**.**all()**.**prefetch\_related('toppings')
**模糊查询**
Entry**.**objects**.**get(headline__exact**=**"Man bites dog")
**exact** “精确”匹配。
Blog**.**objects**.**get(name_\_iexact**=**"beatles blog")
**iexact**大小写不敏感的匹配
Entry**.**objects**.**get(headline__contains**=**'Lennon')
**contains**大小写敏感的包含关系
Entry**.**objects**.**get(headline_\_icontains**=**'Lennon')
**icontains**大小写不敏感的包含关系。
**--------------------------------------------------------------**
关键概念说明:
管理器对应数据库中的表。每个模型都有一个objects管理器用来调用查询方法。管理器只能通过模型的类进行访问不能通过模型的实例进行访问。
查询集:对应数据库中的记录。查询集 是惰性执行的 ——
创建[查询集](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet)不会带来任何数据库的访问。你可以将过滤器保持一整天,直到[查询集](http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html#django.db.models.query.QuerySet)
需要求值时Django 才会真正运行这个查询。所以可以放心大胆的查询。
二者关系:
管理器是查询集的主要来源。

View File

@@ -0,0 +1,64 @@
MEIDIA_ROOT
保存用户上传的目录和系统绝对文件系统路径。
- 处理从MEDIA_ROOT提供的媒体的URL用于管理存储的文件。
如果设置为非空值,则它必须以斜杠结尾。
您将需要将这些文件配置为在开发和生产环境中提供服务。
- 如果您想在模板中使用{{MEDIA_URL}}请在“模板”的“context_processors”选项中添加“django.template.context_processors.media”
MEDIA_URL
引用或者说访问MEIDIA_ROOT中的文件时使用的URL即客户通过浏览器访问的路径。
STATIC_ROOT
用来保存静态文件搭建网站的css库scrip脚本图片默认值为none。收集静态文件进行部署的目录的绝对路径
STATIC_URL
引用STATIC_ROOT中静态文件时使用的URL
- 如果不是
None这将被用作资产定义Media类和staticfiles应用程序的基本路径。
- 如果设置为非空值,则它必须以斜杠结尾。您可能需要将这些文件配置为在开发中提供服务,并且在生产中肯定需要这样做。
- 能够构建静态文件相对路径的URL例如将静态文件存储在应用程序中的静态文件夹中。my_app
/ static / my_app / example.jpg
{% load static %} \<img src="{% static "my_app/example.jpg" %}" alt="My
image"/\>
STATICFILES_DIRS
此设置定义如果FileSystemFinder查找器启用staticfiles应用程序将遍历的其位置例如
如果您使用collectstatic或findstatic管理命令或使用静态文件服务视图。也就是说添加静态文件查找位置的绝对路径
> STATICFILES_DIRS = [ "/home/special.polls.com/polls/static",
> "/home/polls.com/polls/static", "/opt/webfiles/common", ]
- 应将此设置为包含其他文件目录的完整路径的字符串列表
INSTALLED_APPS = (
'django.contrib.admin', \#用来提供数据库管理功能
'django.contrib.auth', \#用来提供用户管理功能,包好访问界面
'django.contrib.contenttypes', \#用来提供:
'django.contrib.sessions', \#用来提供session管理功能
'django.contrib.messages', \#
'django.contrib.staticfiles', \#用来提供静态文件的查找、访问和管理功能。
)
django中自带的app说明
每个APP应该有自己的model、view、templates。
总的APP有一个view和template不需要model

View File

@@ -0,0 +1,29 @@
文件上传字段FileField(upload_to=Node,max_length=100, \*\*options)[source]
- FileField.upload_to
此属性提供了一种设置上传目录和文件名的方式,可以通过两种方式进行设置。
在这两种情况下该值都将传递给Storage.save方法。
- 如果您指定了一个字符串值它可能包含strftime格式将由文件上传的日期/时间替换(以便上传的文件不填满给定的目录)。
例如:
class MyModel(models.Model): \# 文件将会上传到 MEDIA_ROOT/uploads upload =
models.FileField(upload_to='uploads/') \# or... \# 文件将会保存到
MEDIA_ROOT/uploads/2015/01/30 upload =
models.FileField(upload_to='uploads/%Y/%m/%d/')
- 如果使用默认的FileSystemStorage则字符串值将被附加到MEDIA_ROOT路径上以形成存储上传文件的本地文件系统上的位置。
如果您正在使用其他存储空间请检查该存储的文档以查看它如何处理upload_to。
- upload_to也可以是可调用的作为一个函数。
这将被调用来获取上传路径,包括文件名。 此 可调用
必须接受两个参数并返回一个Unix样式的路径带有斜杠以传递到存储系统。
两个参数是:
![clipboard.png](media/94ceeea49b0fbeef8256fd6c4c3e2e32.png)
def user_directory\_path(instance, filename): \# file will be uploaded to
MEDIA_ROOT/user_\<id\>/\<filename\> return
'user_{0}/{1}'.format(instance.user.id, filename) class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)

View File

@@ -0,0 +1,178 @@
**User对象字段**
- **username**
- password
- email
- first_name
- last_name
**创建User**
- User.objects.create\_user() user.save()
- manage.py createsuperuser
- manage.py changepassword username
**验证User的用户名密码**
- **authenticate(username, password)**
**from** **django.contrib.auth** **import** authenticate user **=**
authenticate(username**=**'john', password**=**'secret')**if** user **is**
**not** None: *\# the password verified for the user* **if** user**.**is_active:
**print**("User is valid, active and authenticated") **else**: **print**("The
password is valid, but the account has been disabled!")**else**: *\# the
authentication system was unable to verify the username and password*
**print**("The username and password were incorrect.")
**关于权限User本身设置的两个权限已经够用后台管理员和普通用户**
**web请求中的认证**
- **Django**使用会话session和中间件来拦截request对象到认证系统当中。会在每一个请求上提供一个request.user属性表示当前用户。若果当前用户没有登录则该属性被设置为AnonymousmousUser的一个实例否则是User的一个实例。
- 通过is_authenticated() 区分他们
**if** request**.**user**.**is\_authenticated(): *\# Do something for
authenticated users.* **...else**: *\# Do something for anonymous users.*
**...**
**登录一个用户**
- 从视图中登入一个用户使用login函数接受一个HttpRequest对象和一个User对象。
- login()使用Django的session框架保存用户的信息作为服务器端和客户端记住登录状态的工具。
**from** **django.contrib.auth** **import** authenticate, login **def**
**my_view**(request): username **=** request**.**POST['username'] password **=**
request**.**POST['password'] user **=** authenticate(username**=**username,
password**=**password) **if** user **is** **not** None: **if**
user**.**is_active: login(request, user) *\# Redirect to a success page.*
**else**: *\# Return a 'disabled account' error message* **...** **else**: *\#
Return an 'invalid login' error message.* **...**
**登出一个用户**
- 使用logout()函数。接受一个HttpRequest对象并且没有返回值。即使没有用户登入也不会抛出错误。所有的会话session框架中的数据都将会被清除。
- 能够接受一个URL作为登出后跳转的URL
**只允许登录的用户访问**
- 原始方法使用request.user.is_authenticated()并进行重定向到一个登录页面。或者使用一个新的页面对错误信息进行渲染
**from** **django.conf** **import** settings **from** **django.shortcuts**
**import** redirect **def** **my_view**(request): **if** **not**
request**.**user**.**is_authenticated(): **return**
redirect('**%s**?next=**%s**' **%** (settings**.**LOGIN_URL, request**.**path))
*\# ...*
**from** **django.shortcuts** **import** render **def** **my_view**(request):
**if** **not** request**.**user**.**is_authenticated(): **return**
render(request, 'myapp/login_error.html') *\# ...*
- 使用login_required装饰器比较快捷的方式
**login\_required([**redirect_field_name=REDIRECT_FIELD_NAME**,**
login_url=None**])**
**from** **django.contrib.auth.decorators** **import** login_required
@login\_required**def** **my_view**(request): **...**
主要完成了下面的事如果用户没有登入则重定向到setting.LOGIN_URL并将当前访问的绝对路径传递到查询字符串中如果用户已经登入则正常执行视图。视图的代码可以安全地假设用户已经登入。
默认情况下,在成功认证后用户应该被重定向的路径存储在查询字符串的一个叫做**"next"**的参数中。如果对该参数你倾向使用一个不同的名字,[**login\_required()**](http://python.usyiyi.cn/documents/django_182/topics/auth/default.html#django.contrib.auth.decorators.login_required)带有一个可选的**redirect_field_name**参数
**from** **django.contrib.auth.decorators** **import** login_required
@login_required(redirect_field_name**=**'my_redirect_field')**def**
**my_view**(request):
可以添加一个login_url参数用来作为认证失败后重定向的位置
**from** **django.contrib.auth.decorators** **import** login_required
@login_required(login_url**=**'/accounts/login/')**def** **my_view**(request):
**...**
**给已经登录的用户添加访问限制(两个装饰器估计用不到)**
- 原始方法检查request.user的不同的字段
- **user_passes_test** 装饰器,进行重定向。
- permission_required装饰器检查是否具有权限。
- 对基于类的普通视图进行权限控制可以加装饰器view.dispatch
**密码更改后session会失效**
**用户登录认证的视图(方便快速的完成登录注册等操作)**
**这个真的没看懂怎么用,貌似就是一系列的默认视图,但是……不是很懂**
**扩展已有的用户模型**
你可以创建基于[**User**](http://python.usyiyi.cn/documents/django_182/ref/contrib/auth.html#django.contrib.auth.models.User)
的[代理模型](http://python.usyiyi.cn/documents/django_182/topics/db/models.html#proxy-models)。代理模型提供的功能包括默认的排序、自定义管理器以及自定义模型方法。如果你想存储新字段到已有的**User**里,那么你可以选择[one-to-one
relationship](http://python.usyiyi.cn/documents/django_182/ref/models/fields.html#ref-onetoone)来扩展用户信息。这种
one-to-one 模型一般被称为资料模型(profile
model),它通常被用来存储一些有关网站用户的非验证性( non-auth
)资料。例如,你可以创建一个员工模型 (Employee model)
**from** **django.contrib.auth.models** **import** User **class**
**Employee**(models**.**Model): user **=** models**.**OneToOneField(User)
department **=** models**.**CharField(max_length**=**100)
在视图中的访问方式,可以直接查找代理中的其他数据类型
**\>\>\>** u **=** User**.**objects**.**get(username**=**'fsmith')**\>\>\>**
freds_department **=** u**.**employee**.**department
要将个人资料模型的字段添加到管理后台的用户页面中,请在应用程序的**admin.py**定义一个[**InlineModelAdmin**](http://python.usyiyi.cn/documents/django_182/ref/contrib/admin/index.html#django.contrib.admin.InlineModelAdmin)(对于本示例,我们将使用[**StackedInline**](http://python.usyiyi.cn/documents/django_182/ref/contrib/admin/index.html#django.contrib.admin.StackedInline)
)并将其添加到**UserAdmin**类并向[**User**](http://python.usyiyi.cn/documents/django_182/ref/contrib/auth.html#django.contrib.auth.models.User)类注册的:
**from** **django.contrib** **import** admin **from**
**django.contrib.auth.admin** **import** UserAdmin **from**
**django.contrib.auth.models** **import** User **from**
**my_user_profile_app.models** **import** Employee *\# Define an inline admin
descriptor for Employee model\# which acts a bit like a singleton***class**
**EmployeeInline**(admin**.**StackedInline): model **=** Employee can_delete
**=** False verbose_name_plural **=** 'employee'*\# Define a new User
admin***class** **UserAdmin**(UserAdmin): inlines **=** (EmployeeInline, ) *\#
Re-register UserAdmin*admin**.**site**.**unregister(User)
admin**.**site**.**register(User, UserAdmin)
这些Profile models在任何方面都不特殊它们就是和User
model多了一个一对一链接的普通Django models。
这种情形下,它们不会在一名用户创建时自动创建, 但是
**django.db.models.signals.post_save** 可以在适当的时候用于创建或更新相关模型。
注意使用相关模型的成果需另外的查询或者联结来获取相关数据,基于你的需求替换用户模型并添加相关字段可能是你更好的选择。但是,在你项目应用程序中,指向默认用户模型的链接可能带来额外的数据库负载。
为了表明这个模型是对于那个给定的站点我们还需要配置一个AUTH_PROFILE_MODULE这是一个字符串包含两部分信息由点号相连
- app名大小写敏感一般是你使用manage.py startapp创建时用的名称
- 你自定义的模型名称,大小写不敏感
比如app名为accounts模型名为UserProfile
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
一旦一个用户档案模型额外信息模型被定义然后用上述方法指明每一个user对象都会有一个方法--get_profile()--去返回跟该用户相关的额外信息
**因为新建的数据库还没有迁移,所以与用户相关的功能还不能实现。那么可以先实现用户登录香瓜的功能。**
**如用户的注册、登录、登出等功能的相关控制。然后在实现与用户相关的功能,并添加权限控制。**
**1. 通过代理的方式建立UserNoramal用户扩展类。**
**配置UserNormal为User表的内联表在管理页面进行管理。**
**由于没有迁移数据库不能运行admin**
**2. 从登录页面开始继续下去,已经完成了各个页面的配置工作。**

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -0,0 +1,20 @@
**ItemLoader是为了将获取文本进行分解装载到相应的ItemLoader当中。**
**具体方法:**
**def** **parse**(self, response): l **=** ItemLoader(item**=**Product(),
response**=**response) l**.**add_xpath('name', '//div[@class="product_name"]')
l**.**add_xpath('name', '//div[@class="product_title"]')
l**.**add_xpath('price', '//p[@id="price"]') l**.**add_css('stock', 'p\#stock]')
l**.**add_value('last_updated', 'today') *\# you can also use literal values*
**return** l**.**load_item()
ItemLoader在每个字段中包含了一个输入处理器和一个输出处理器。
输入处理器收到数据时理科提取数据通过add_xpath(),add_css(),add_value()方法
之后输入处理器的结果被手气起来并保存到ItemLoader内。
收集到所有的数据后调用ItemLoader.load_item()方法来填充并得到填充后的Item对象。
这是当输出处理器和之前手机到的数据被调用。数据的结果是被分配多啊Item的最终值。

View File

@@ -0,0 +1,6 @@
\>
准确的说scrapy主要就有两部分可以编辑一个使用来处理数据的scrapy.Items,另一个用来仓库
Item的操作包括创建、获取字段的值、设置字段的值、后去所欲的键、获取product列表、获取product字段、社赋值和浅复制、集成扩展item。
Item对象的操作 fields内置字段是item生命中使用到的field对象的名字是一个字典。

View File

@@ -0,0 +1,65 @@
全局命令\<不需要要项目,在命令行中直接运行\>
scrapy startproject myproject
\- 创建一个名为myproject的scrapy项目
scrapy genspider [-t template] \<name\> \<domain\>
\- 创建一个新的spider(-l 列出spider的模板-d 查看模板的内容 -t 使用这个模板)
scrapy -h
\- 查看所有可用的命令
scrapy crawl \<spider\>
\- 使用spider进行爬虫
scrapy check [l] \<spider\>
\- 运行contract检查
scrapy list
\- 列出所欲可能的spider
scrapy edit \<spider\>
\- 使用设定的编辑器编辑spider
scrapy fetch \<url\>
\- 使用scrapy下载器Downloader下载给定的URL并将获取到的内容标准输出
scrapy view \<url\>
\- 用来查看spider获取到的页面因为可能spider获取到的页面跟想要的不同。
scrapy shell [url]
\-scrapy 终端能够使用scrapy内部命令对url返回的内容进行操作。
scrapy parse \<url\> [options]
\- 获取给定的URL并使用相应的spider分析处理。
scrapy settings [options]
\- 获取scrapy的设定。
scrapy runspider \<spider_file.py\>
\- 在未创建项目的情况下运行在一个编写在python文件中的spider
scrapy -version [-v]
\- 输出scrapy版本
scrapy deploy []
\- 将仙姑部署到scrapyd服务。
scrapy bench
\- 运行benchmark测试。

View File

@@ -0,0 +1,44 @@
![scrapy_architecture.jpg](media/8c591d54457bb033812a2b0364011e9c.jpeg)
scrapy引擎
调度器
Spiders
下载器
Item Pipeline
itemloader用来装载item用来容纳itempipeline用来过滤。也负责了指明了存好数据的item的数据流动的方向。itemloader是活动在原始数据和item之间的桥梁。itempipeline是活动在item和具体存储数据的位置之间的桥梁。比如用来操纵数据库、用来写入文件用来提供下一次爬虫的相关信息。
下载器中间件
由调度器具体指挥能够根据引擎发送的request对象封装真正的request请求并且设置请求的响应参数。不同的下载器中间件能够完成不同的任务。
Spider中间件
引擎和Spider之间的钩子。用来处理Spider发送给引擎的request和Item和引擎发送给Spider的response。有点像网络的分层没一层都向发送数据中添加一点内容每一层都从接受数据中获得一点内容。有很多中间件可以在这里过滤掉一些错误。另外如果错误能够越提前的发现则越有利于提高效率。
扩展Extension和信号signal
框架提供了一个很好的扩展机制。在配置文件中声明如果想要在某个地方进行扩展可以通过这种方式在要扩展的地方产生一个独特的信号。然后在扩展类中接受这个信号。接下来对接受到的信号和数据进行处理。最后将执行权返回。通过配置文件中的EXTENSION架子啊和激活。
而且信号能够诶眼催处理,停止处理等。有点像事件驱动机制一样。当产生一个事件,监听器就能监听到,然后做出响应的反应。这种方法,的确有利于扩展。
Link Extractors
从response对象中抽取能够最脏你刚是被过量欧文链接的对象。
Feed exports
在存储数据数据之前对数据进行格式化。数据存储的方式序列化的方式主要通过一下几个类。JSON,JSON
LINES,CSV , XML ,
PICKLE,MARSHAL。同时也用来定义数据存储的方式可以是本地文件系统FTPS3标准输出等。通过URI类实现具体存储的方式。
异常Exception
内置了异常参看手册。主要的异常类有DropItem
有itempipeline跑出用来停止处理item。CloseSpider由Spider的回调函数抛出用来停止spider。IgnoreRequest
由调度器或者下载中间价抛出生命忽略该request。NotConfigured
由任何组件抛出声明其仍然保持关闭。NotSupported声明了一个不支持的特性。

View File

@@ -0,0 +1,43 @@
XPath使用路径表达式来选取XML文档中的节点或者节点集合。节点是通过path或者步来选取的。
1\. 通过已经有的表达式选取节点、元素、属性和内容
nodename 选取此节点的所有子节点
/ 从根节点开始选取
// 从匹配选择的当前节点选择文档中的节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
2\. 带有位于的路径表达式,使用[ ]来表示当前节点被选取的一些条件
/bookstor/book[price\>35]/title
3\. 通配符来选取未知的元素一般也用python的re表达式
\* 匹配任何元素的节点
@\* 匹配带有任何属性节点(没有属性的节点不行)
node() 匹配任何类型的接待你。
对于CSS来说选择器与HTML和CSS相关。
.class intro 查找类别下的元素
\#id \#firstname id=\*的所有用户
element p 选择所有的元素
elementelement 并列选择
element element 父子选择
element\>element 父元素选择
element element

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@@ -0,0 +1,20 @@
爬取网站最常见的任务是从HTML源代码中提取数据。常用的库有BeautifulSoup。lxml库Xpath。
Selector 中Xpath和CSS的使用
标签是节点 ,可以有层级
属性使用@来调用
内容要用text()来调用
条件要在[ ]写明白也可以是contains[]
//表示获得所有的某一个标签
./表示下一级的方法
可以使用正则表达式最原始的过滤。
response**.**xpath('//a[contains(@href,
"image")]/text()')**.**re(r'Name:\\s\*(.\*)')

View File

@@ -0,0 +1,73 @@
Spider类定义了如何爬去某个网站包括爬去的动作、分析某个网页。
这个流程再清晰一下 发送请求-\>返回网页-\>分析处理生成数据-\>保存。
对爬虫过程的描述:
1. 初始的URL初始化Request设置回调函数。下载完成生成response并作为参数传给该回调函数。start_requests()来获取start_urls.
2. 在回调函数内分析返回的网页内容返回Item对象或者Request或者一个包括而止的可迭代的容器。放回的Response对象经过处理调用callback函数。
3. 在回调函数内可以使用选择器Xpath解析器等任何解析器来分析内容并根据分析生成数据item
4. 最后spider返回的item将被存到数据库中或者导入文件当中。
Spider crawl mysqpider -a category=electronics
传递spider的参数限定爬去网站的部分。
函数的调用流程
spider的构成
name 名字,作用域内唯一。
allowed_domains可选包含了spider爬取的域名domain列表list
start_urls 从该列表脏欧冠呢开始进行爬去。
start_requests()必须返回一个可迭代对象。该对象包含了spider用于爬去的第一个Request。make_reuest_from_url()将被调用来创建Request对象。
make_requests_from_url(url)该方法接受URL返回requests对象。将URL转换为Request对象。parse()作为回调函数。
parse(response)当response没有指定回调函数时该方法是scrapy处理下载的response的默认方法。parse负责处理response并返回处理的数据以及跟进的URL。所有的Request回调函数必须范式一个包含Request或Item的可迭代的对象。
log(mewwage[,level,component])日志记录
closed(reason)spider关闭时这个函数被调用。
Spider的样例
**import** scrapy**from** myproject.items **import** MyItem**class**
**MySpider**(scrapy**.**Spider): name **=** 'example.com' allowed_domains **=**
['example.com'] start_urls **=** [ 'http://www.example.com/1.html',
'http://www.example.com/2.html', 'http://www.example.com/3.html', ] **def**
**parse**(self, response): sel **=** scrapy**.**Selector(response) **for** h3
**in** response**.**xpath('//h3')**.**extract(): **yield** MyItem(title**=**h3)
**for** url **in** response**.**xpath('//a/@href')**.**extract(): **yield**
scrapy**.**Request(url, callback**=**self**.**parse)
CrawlSpider ( scrapy.contrib.spiders.CrawlSpider)
> rules 包含多个Rule对象的列表。
> parse_start_url(response)当start_url的请求返回时该方法被调用。
XMLFeedSpider
CSVFeedSpider
SitemapSpider
爬取规则(scrapy.contrib.spiders.Rule())
link_extractor 是一个LinkExtracto对象定义了如何从爬取到的页面提取链接。
callback当从link_extractor中获取到链接之后将会调用该函数。该回调函数接受一个response作为第一个参数并返回一个包含Item以及Request对象的列表。不要使用parse
cb_kwargs传递给回调函数的参数的字典。
follow是一个Boolean从response中提取的链接是否需要跟进。
process_links该方法用来过滤也是回调函数。
process_request该规则提取到的每个request队徽调用这个函数并且返回一个request或者None。

View File

@@ -0,0 +1,66 @@
spider 的使用说明:
继承scrapy.spider
name spider的名字
start_urls初始链接
request 发送请求并且捕获相应通过回调函数parse处理response相应
request函数能够发送请求request函数需要一个回调函数来接受请求。默认的request函数调用了parse但是在多次request中需要设置不同的parse函数来处理多次请求
python
回调函数的意思就是在一个函数的某个地方通过一个函数指针调用另外一个函数使得函数跳转。因为python是脚本所以在没有返回值的python函数执行时如果函数跳转到其他地方并不会返回一个值到原来的地方。
轮换useragent的目的
当你使用同一个浏览器的时候同一个useragent会因为过度浪费服务器资源而被禁掉。
scrapy的一些内置特性
scrapy内置的数据抽取其css/xpath/re
scrapy内置结果的输出csv,xml,json
自动处理编码
有丰富的内置扩展
cookies session 客户端和服务器端的缓存机制
Http featurescompressionauthenticationcaching
user-agent spoofing轮换useragent用户代理的意思浏览器的类型
robots.txt 网站中用来告诉爬虫那些资源时可以被访问的,哪些资源时不能被访问的。
crawl depth restriction 限制爬去的深度
itme Pipeline的作用
清洗HTML数据
验证抓取到的数据
检查是否存在重复
存储抓取到的数据到数据库中。
关于parse分析response后返回值的问题
如果parse的返回值是一个request将进行更深层侧的爬虫抓去。
如果parse的返回值是一个item则程序的执行权就会交个itempipeline然后pipeline负责处理返回的item对象。包括这些item对象是否合理。
一个简单爬虫的具体分析步骤:
创建工程
编写item用来结构化分析数据使用
编写spider用来爬去具体的网站
编写和配置pipeline主要实现对生成的item的处理
调试运行代码

View File

@@ -0,0 +1,13 @@
对框架的基本内容有所理解了:
上图:
刚刚发现只有xicidaili.com能够空头访问而微信和百度都不能空头访问。这说明代码运行不了的原因是没有加载头部信息。不不不。xicidaili.com也不饿能进行空头访问知识他在访问的时候自动加载了头部而其他网站都没有加载默认配置为毛子
1\. 增加并发,
通过这一次的运行知道两件事情:
问题一定出在最简单的地方,往往是你对一些习惯性的东西太不了解导致的。
阅读日志文档,了解基础知识真的很重要呀呀呀呀!!!!愚蠢的殷康龙

1
Python/Scrapy/注意.md Normal file
View File

@@ -0,0 +1 @@
以后逐步将手写笔记改为网络端。(节约时间、便于调整,有利于复习)

View File

@@ -0,0 +1,26 @@
**\>程序设计的基础知识**
\>\>程序的定义:为了完成某项任务解决某个问题,计算机及执行的一定的指令
\>\>计算机:实现程序的机器,Enia宾夕法尼亚大学-电子管-晶体管-集成电路
\>\>cup构成冯诺依曼的计算机结构输入设备-存储器-输出设备-控制器-计算器
**\>人与机器的沟通**
\>\>程序设计语言:汇编语言-低级语言-高级语言python-Java
\>\>分类编译型语言source code -compiler- object
CODe。解释性语言sourcecode-interpreter-output
\>\>创始人:吉多·范·罗苏姆蟒蛇
\>\>python解释性语言可移植性强执行效率低设计哲学优雅明确简单
**\>第一个程序hello world**
\>\>print python
\>\>命令行Linux系统下)优点:无需创建文件,立即看到裕运行的结果
脚本IDE编辑器适合编写大型程序更容易纠错更容易修改和执行

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

View File

@@ -0,0 +1,160 @@
当你创建了一个列表,你可以逐项地读取这个列表。这个过程就是迭代
**[python]** [view
plain](http://blog.csdn.net/a168861888m/article/details/78293251)
[copy](http://blog.csdn.net/a168861888m/article/details/78293251)
1. \<span style="font-family:'Times New Roman';font-size:14px;"\>\>\>\> mylist
= [1, 2, 3]
2. \>\>\> **for** i **in** mylist:
3. ... **print**(i)
4. 1
5. 2
6. 3\</span\>
mylist是一个可迭代对象。当你使用一个列表生成式的时候你创建了一个列表也就是一个可迭代对象
**[python]** [view
plain](http://blog.csdn.net/a168861888m/article/details/78293251)
[copy](http://blog.csdn.net/a168861888m/article/details/78293251)
1. \<span style="font-family:'Times New Roman';font-size:14px;"\>\>\>\> mylist
= [x\*x **for** x **in** range(3)]
2. \>\>\> **for** i **in** mylist:
3. ... **print**(i)
4. 0
5. 1
6. 4\</span\>
所有你可以使用 "for...in..."的都是可迭代对象:列表,字符串,文件等等
你经常使用它们因为你可以如你所愿的读取其中的元素,但是你把所有的数据都存贮在内存里,如果你有许多数据的话,这种做法不会是你想要的
生成器
生成器都是可以迭代的,但是你只可以迭代它们一次,因为他们并不是把所有的数据存贮在内存中,它是实时的生成数据
**[python]** [view
plain](http://blog.csdn.net/a168861888m/article/details/78293251)
[copy](http://blog.csdn.net/a168861888m/article/details/78293251)
1. \<span style="font-family:'Times New Roman';font-size:14px;"\>\>\>\>
mygenerator = (x\*x **for** x **in** range(3))
2. \>\>\> **for** i **in** mygenerator:
3. ... **print**(i)
4. 0
5. 1
6. 4\</span\>
看上去都是一样的,除了使用()而不是 []。但是你不可以再次使用 for i in
mygenerator
因为生成器只能被逆代一次他们先计算出0然后就丢掉了0然后再继续逐项计算1计算4
Yield
yield是一个类似 return的关键字不同的是这个函数返回的是一个生成器
**[python]** [view
plain](http://blog.csdn.net/a168861888m/article/details/78293251)
[copy](http://blog.csdn.net/a168861888m/article/details/78293251)
1. \<span style="font-family:'Times New Roman';font-size:14px;"\>\>\>\> **def**
createGenerator():
2. ... mylist = range(3)
3. ... **for** i **in** mylist:
4. ... **yield** i\*i
5. ...
6. \>\>\> mygenerator = createGenerator() \# create a generator
7. \>\>\> **print**(mygenerator) \# mygenerator is an object!
8. \<generator object createGenerator at 0xb7555c34\>
9. \>\>\> **for** i **in** mygenerator:
10. ... **print**(i)
11. 0
12. 1
13. 4\</span\>
这个例子没什么用途,但如果你的函数会返回一大批你只需要阅读一次的数据的时候,这是很方便的。
为了精通
yield你必须理解当你调用这个函数的时候函数里的代码是不会马上执行的。这个函数只是返回生成器对象这有点蹊跷不是吗
那么函数的代码什么时候开始执行呢使用for迭代的时候
现在到了比较的难的一部分:
第一次迭代的时候你的函数开始执行从开始到达yield关键字然后返回第一次迭代的值。然后每次执行这个函数都会继续执行你在函数内部定义的那个循环的下一次再返回那个值直到没有可以返回的值。如果生成器内部没有定义yield
关键词这个生成器被认为是空的。也有可能是因为循环已经结束或者没有满足“If/else”条件
\----------------------------------------------------------------------------------------------------------------------------------------(我是分割线)
更深入聊一下:什么时候使用 field 而不是 return
yield语句暂停函数的执行并向调用者发送一个值但保留足够的状态以使函数能够在其被关闭的位置恢复。
恢复后,该功能在最后一次产量运行后立即继续执行。
**这允许其代码随时间产生一系列值,而不是一次计算它们,并将其像列表一样发送回来。**
我们来看一个例子:
**[python]** [view
plain](http://blog.csdn.net/a168861888m/article/details/78293251)
[copy](http://blog.csdn.net/a168861888m/article/details/78293251)
1. \<span style="font-family:'Times New Roman';font-size:14px;"\>**def**
simpleGeneratorFun():
2. **yield** 1
3. **yield** 2
4. **yield** 3
5.
6. \# Driver code to check above generator function
7. **for** value **in** simpleGeneratorFun():
8. **print**(value)\</span\>
输出:
1 2 3
return返回一个指定的值给它的调用者而yield可以产生一个值序列。当要遍历一个序列但又不想将整个序列存储在内存中的时候我们应该使用yield
yield用于Python生成器中。
一个生成器函数被定义为一个正常的函数,但是只要它需要生成一个值,就应该使用 yield
关键字而不是return。 如果 def 的 body 包含 yield则该函数自动成为生成器函数。
写博客也参考了一些资料(学习一般都是看英文的):
1https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do?page=1&tab=votes\#tab-top
2http://www.geeksforgeeks.org/use-yield-keyword-instead-return-keyword-python/

65
Python/python2/函数.md Normal file
View File

@@ -0,0 +1,65 @@
**\>函数**
\>\>函数定义:完成特定功能的一个语句组,这组语句可以作为一个单位使用,并且给他求个名字,通过函数名执行
\>\>语法:
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51873452)
[copy](http://blog.csdn.net/estom_yin/article/details/51873452)
1. \<span style="font-size:18px;"\> **def** print\_sum(start, stop):
2. """ to calculate the sum from start to stop """
3. result = 0
4. **for** i **in** range(star, stop + 1):
5. result += i
6. **print** 'sum is', result\</span\>
> 第一行定义了一个函数,关键字 def ,函数名 print_sum函数参数start stop
\>\>函数调用
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51873452)
[copy](http://blog.csdn.net/estom_yin/article/details/51873452)
1. \<span style="font-size:18px;"\>print\_sum(a, b)\</span\>
\>\>参数说明
> 形式参数和实际参数
> 缺省参数,定义实参时,给参数赋值
\>\>返回值
> return 语句会终止当前的函数执行
> 返回一个变量
\>\>变量的作用域
> 局部变量:只能在程序特定部分起作用
> 全局变量:能在程序的全局起作用
> 名称的屏蔽作用
> global x 表明x是一个全局变量声明
> pass 语句可作为一个占位符,用于表示此处省略的大量语句
\>\>函数的作用:
> 可以将一个打的问题,分解成一个小的函数,有利于解决问题
> 可以进行信息的封装和隐藏
**\>琐碎的函数知识总结**
\>\>if month in(1, 3, 5, 7, 8, 9, 11, 12):函数in可以表示一个选择范围

View File

@@ -0,0 +1,279 @@
\>列表简介
\>\>是一种内建的数据结构,用来存储一系列的元素
\>\>同JS一样由于解释性语言不必声明数据类型所以数组的元素也可以很灵或的不相同。
\>列表的运算
> index索引运算[]
> 切片运算:[:]
> 拼接运算+
> 重复运算\*
> 成员运算in
> 长度运算len
> 循环for
\>列表方法:
> list.intex()可以返回任意的方法
> my_list[2] = a \#元素赋值
> my_list.append()\#末尾追加元素
> my_list.extend()\#末尾追加子表
> my_list.insert()\#任意位置插入元素
> my_list.pop()结尾删除元素
> my_lise.sort()\#排序
> my_list.remove()\#删除任意位置元素
> my_list.reverse()\#倒序
\>列表应用
\>\>内建函数sum()求和max求最大值min()求最小值
\>\>列表名本身就是一种指针和地址。所以在赋值是只是一个指针的指向赋值给另一个指针的指向
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>程序一\</span\>
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>a = [1, 2, 3, 4]
2. b = a
3. b[1] = 100
4. **print** a[1]
5. 程序二
6. a = [1, 2, 3, 4]
7. b = a[:]
8. b[1] = 100
9. **print** a[1]\</span\>
程序一的输出100因为a和b指向同一个位置
程序二的输出1因为a和b指向不同的位置。
\>\>交换列表中两个元素的值
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>**def** swap(lst, a, b)
2. tmp = lst[a]
3. lst[a] = lst[b]
4. lst[b] = lst[a]
5. x = [10, 20, 30]
6. swap(x, 0, 1)\</span\>
\>\>查找并返回元素位置
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>**def** search(lst, x):
2. **for** i **in** range(len(lst)):
3. **if** lst[i] == x:
4. **return** i
5. **return** -1\</span\>
也可以直接使用lst.index(待查找元素)直接进行查找
\>\>时间复杂度的计算
\>二分查找
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>**def** bi\_search(lst, v):
2. low = 0
3. up = len(lst) - 1
4. **while** low \<= up
5. mid = (low + up) / 2
6. **if** lst[mid] \< v:
7. low = mid + 1
8. **elif** lst[mid] == v:
9. **return** mid
10. **else**:
11. up = mid - 1
12. **return** -1\</span\>
\>排序
\>\>选择排序
![715154122626.png](media/36645b2c7df50743cafd69bff4f6f00e.png)
\>\>冒泡排序
![715154128126.png](media/a524121dffc0de426130c95b7f05fbcf.png)
\>\>使用内置函数
> sortedlst
> lst.sort()
\>嵌套列表
students = [ ['zhang', 84], ['wang', 77], ['li', 100], ['zhao',53] ]
\>列表的解析
\>\>作用:一种有源列表创建新列表的方法
\>\>语法:[表达式for 变量 in 列表 if 条件]
生成函数-变化范围-约束条件
普通方法
> lst = []
> for x in range(1, 10)
> lst.append(x\*\*2)
> print lst
列表解析法:
> lst = [x\*\*2 for x in range(1,10) if x % 2 == 0]
> 生成函数x\*\*2生成范围1-10生成条件x%2==0
\>定义匿名函数lambda
g = lambda x: x \*\* 2
print f(8)
所以可以用一下程序实现嵌套列表的值排序
students = [ ['zhang', 84], ['wang', 77], ['li', 100], ['zhao',53] ]
students.sort(key = lambda x: x[1], reverse = true)
\>元组
\>\>注意事项
1、元组同字符串一样具有不可变性本质上是一个列表
2、append、extend、del等改变列表内容的函数不再适用其它函数可以用
3、用括号直接创建元组引号直接创建字符串方括号直接创建列表
4、元组的括号可以省略直接用逗号隔开相同元组里的不同项
\>\>使用元组赋值
使用元组交换两个值
a, b = b , a
name, domai = 'car@163.com'.split('@') //这样就直接将值赋给两个变量了。
\>\>函数和元组
使用元组可以返回多个函数值
![715160502150.png](media/d8ec8dcdb684175683aa827cdec3d19b.png)
\>\>DSU模式decorate,sort,undecorete修饰排序反修饰
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>**def** sort_by_length(words):
2. \#decorate
3. t = []
4. **for** word **in** words:
5. t.append((len(word),word))
6. \#将元素和元素长度组成一个二元组
7. \#sort
8. t.sort(reverse = true)
9.
10. \#undecorate
11. res = []
12. **for** length, word **in** t:
13. res.append(word)
14. **return** res
15.
16. \</span\>
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51916941)
[copy](http://blog.csdn.net/estom_yin/article/details/51916941)
1. \<span style="font-size:14px;"\>
2.
3. words.sort(key = **lambda** x:len(x),reverse =true)\</span\>
//巧妙地利用了元组对应的灵活性完成了合成和分割

View File

@@ -0,0 +1,60 @@
\>基本的数据类型
\>\>字符串string 使用’或“
\>\>整数integer 21 025 0x15
\>\>浮点数1.48 2.1e2有精度损失
\>\>布尔型boolean True或者False
\>\>复数 1+4j
\>\>使用type函数查看数据类型type小明区分类型
\>运算符与表达式
\>\>算数运算5.0 / 9 \* 32-8隐式类型转换bool-\>int-\>float-\>complex
\>\>+ - \* / % \*\*(指数)
\>\>math模块实现更多算术运算
模块实现一定功能的python脚本的集合
方法import module_name
查看modeldir(math)
查看functionhelpname
\>\>关系运算== != \< \> \<= \>=结果True False
\>\>逻辑运算符 and or not
and
返回最后一次判定的值因为and只有全部判定结束后或者判定到假是才会停止判定所以其返回值可能是最后一个真值或者某个第一个假值
or返回第一个遇到的真值或者最后一个假值当or中有一个是真值是他就会返回这个值
\>\>运算顺序:括号具有最高优先级,由内到外结合。括号-一元运算-算数运算乘除取余//-算数运算加减-比较运算-逻辑非-逻辑与-逻辑或-赋值运算
规则一:自上而下括号最高逻辑最低。
规则二:自左向右依次结合统计运算自左向右
\>变量与简单的输入输出
\>\>变量的定义:用于引用绑定对象的标识符
\>\>语法:变量名=对象(数值、表达式)
\>\>普通的赋值运算符,增量赋值运算符
\>\>变量标识符的定义和C++相同,而且大小写敏感
\>\>raw_input(“输入的提示符”)读取键盘输入,将所输入作为字符看待,需要对输入的字符进行强制的类型转化
\>\>print
“输出提示符”将对象的值输出到控制台上;使用逗号分隔许多对象,输出后会自动添加空格;\\n
\\\\ \\t\\a \\'

View File

@@ -0,0 +1,105 @@
**\>字典结构**
\>\>键值对融合了PHP中的特点
\>\>创建字典,使用成对的花括号{ },使用冒号表示键值对
> 例如my_dict = {'John':879798,'Bob':8757,'mike':725466}
> 其他方法dict(zip([1,2,3],[4,5,6]))或dict([(1,4),(2,5),(3,6)])
\>\>访问字典:使用方括号[ ] ,使用键作为索引
> 例如print my_dict print my_dict['tom']
\>\>字典运算符和方法
> lenmy_dict字典中键值对的数量
> key in my_dict快速判断key是否为字典中的键=\>my_dict.has_key(key)
> for key in my_dict:能够遍历数组中所有的键(不是值)
> my_dict.items()全部的键值对以列表的形式存在好像Python中称数组为列表吧
> my_dict.keys() 全部的键
> my_dict.values()全部的值
> my_dict.clear() 清空字典
\>\>关于文件处理中涉及到的一些函数
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/52345031)
[copy](http://blog.csdn.net/estom_yin/article/details/52345031)
1. \# reading the essay and count the top ten using words
2.
3. f = open('emma.txt')
4.
5. word_freq = {}
6.
7. **for** line **in** f:
8. words = line.strip().split()
9. **for** word **in** words:
10. **if** word **in** word_freq:
11. word_freq[word] += 1
12. **else**:
13. word_freq[word] = 1
14.
15. freq_word = []
16. **for** word, freq **in** word\_freq.items():
17. freq\_word.append((freq, word))
18.
19. freq\_word.sort(reverse=True)
20.
21. **for** freq, word **in** freq\_word[:10]:
22. **print** word
23. f.close()
**\>集合**
\>\>定义:无需不重复元素的集合,和字典相同没有值,只有键
\>\>创建集合x = set() x = {key1,key2,...}
\>\>添加和删除x.add('body') x.remove('body')
\>\>集合的运算符
> \-差集
> &交集
> \|并集
> !=不等于判断
> ==判断相等
> in成员运算
> for枚举运算

132
Python/python2/字符串.md Normal file
View File

@@ -0,0 +1,132 @@
\>字符串的定义
\>\>字符串是一个字符的序列,可以使用‘单引号’或者“双引号”表示。
\>\>使用‘’‘三引号’‘’表示时,可以保留字符串的格式信息。
\>\>可以使用转义字符表示字符串内部的引号。/n回车换行/t制表符
\>字符串的基本运算
\>\>len(字符串):返回字符串的长度
\>\> + 拼接操作name = first_name + "jordan"
\>\> \* 重复操作name \* 3 = "mike mike mike"
\>in运算
\>\> in
判断一个字符串是不是另一个字符串的子串大小写敏感返回一个true或false
> name = 'michael jordan'
> 'a' in name
> 返回true
\>\>for语句
> my_str = "hello word"
> for char in my_str
> 循环体
\>字符串索引index
\>\>字符创中每个字符都有个索引值下标索引0从前向后或-1从后向前开始
\>\>将其视为数组
\>字符串切片(将字符串视为字符串数组)
> 变量名[start:finish:conuntBy]获得子串
> start子序列开始的所以
> finish子序列结束位置的下一个位置
> countby字符串的方向和步长同range的第三个参数当取负数时逆向输出
\>\>字符串的不可变性
> 一个字符串一旦生成内容不可改变,不支持每项的赋值。
> 通过切片改变某个下标对应的字符。
\>\>通过切片生成新的字符串
my_str = my\_str[:1] + 'a' + my_str[2:]
\>\>通过切片获取逆字符串
reverse_str = my\_str[ : :-1]
\>字符串对象提供的函数(又称为方法)
> .replace('被替换的字符','新的字符'):返回新的字符串,不能修改原来字符串的内容。
> .find('查找字符'):查找一个字符
> .split():在制定的地方(默认是空格处),进行切分,返回一个字符串数组。
\>\>文件操作:
> 打开文件
> f =open(filename, mode)/mode=r or w
> 按行读取文件内容
> for line in f:
> pass
> 关闭文件:
> f.close()
> 写入文件
> f.write()
\>\>定义函数判断是否是回文字符串
非递归算法
递归算法
\>字符串比较
\>\>按字典顺序进行比较可以直接使用大于小于号返回true或者false
\>字符串的格式化输入输出
\>\>print "Hello{}good{}.".format(5,'DAY')
用中括号代替需要输出的字符,然后在中括号中进行格式化操作布局,调用.format对象的方法写入输出的内容。
\>\>例如
print 'pi is {: .4f}'.format(math.pi)
print 'pi is {:e}'.format(math.pi)
\>python的正则表达式
判断整个字符串name == 'Michael
判断是否 以 Mi 开始name[:2] == 'Mi
包含 cha 子串:'cha' in name
是否包含 c?a 子串:
是否包含 c\*e 子串?
.表示任意字符
\\d表示一系列数字
[a - z]表示任意一个小写字母

View File

@@ -0,0 +1,3 @@
基本语法规则
![pyre_ebb9ce1c-e5e8-4219-a8ae-7ee620d5f9f1.png](media/fb96ec92f6caab4ab0ac9fe60df68ddc.png)

View File

@@ -0,0 +1,74 @@
\>选择结构
\>\>程序流程图:用简单的图形表示问题的解决步骤;起止框,处理匡,判断框,文档框,流程线,圆形,输入输出框
\>\>语法python中大括号不是分区作用是靠语句块的缩进来体现语句块术语的范围
if 条件:
缩进语句块
其余的语句
if 条件:
缩进语句块
else
缩进语句块
\>\>if语句支持嵌套
\>\>多分支结构elif 条件==else if
条件,有助于简化缩进,是画面更加清晰,可读性更高
涉及到两个典型的例子elif计算多分支结构领先是否安全的例子
\>循环结构
\>\>while条件判断成立则执行循环体不成立则不执行
初始化语句
while 条件语句:
循环体
其它语句
\>\>break结束当前循环体
\>\>continue结束这次循环或者说开始新的循环
\>\>for循环
for element in object
循环体
\>\>range(startstopstep)生成连续整数
\>\>穷举法的使用-鸡兔同笼问题
\>\>循环的嵌套问题
\>程序控制结构的练习题
\>\>if-else 句型
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51854060)
[copy](http://blog.csdn.net/estom_yin/article/details/51854060)
1. **for** i **in** range(2,x):
2. **if** x % i == 0 :
3. **break**
4. **else** :
5. prin 'x is a prime'
当else在循环外与for对齐的时候说明了一个问题有无数个if与else对应当其中的任何一个if执行后都不在执行else否则若if没有执行过则会执行else

View File

@@ -0,0 +1,103 @@
\>递归的实现:
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51892697)
[copy](http://blog.csdn.net/estom_yin/article/details/51892697)
1. \<pre name="code" **class**="python"\>**def** p(n):
2. **if** n ==1 **or** n == 0:
3. **return** 1
\>递归的设计:
> 将问题分解成许多同构的问题,然后以相同的方式解决最终分解的小问题。
> 递归的要素:
> 递归执行的操作
> 递归的结束条件
> 递归的参数传递
\>实例一:兔子序列(菲波那切数列,在自然界一些动植物身上都有体现)
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51892697)
[copy](http://blog.csdn.net/estom_yin/article/details/51892697)
1. **def** fib(n):
2. **if** n == 1 **or** n == 2:
3. **return** 1
4. **else**:
5. **return** fib(n - 1) + fib(n - 2)
6. **print** fib(20)
\>实例二:汉诺塔问题
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51892697)
[copy](http://blog.csdn.net/estom_yin/article/details/51892697)
1. **def** hanoi(n, A, B, C):
2. **if** n == 1:
3. **print** "move", n, "from", A, "to", C
4. **else**:
5. hanoi(n - 1, A, C, B)
6. **print** 'move', n, 'from', A, 'to', C
7. hanoi(n - 1, B, A, C)
8.
9. hanoi(10, 'left', 'Mid', 'Right')
\>实例三:停车问题
> 要求:在固定长度的马路上随机停车,根据车身长度以及随机性特点确定,马路长度与停车数量的关系
**[python]** [view
plain](http://blog.csdn.net/estom_yin/article/details/51892697)
[copy](http://blog.csdn.net/estom_yin/article/details/51892697)
1. **import** random
2. \#if the w big enough, lim parking to 3.7472 named Reni constance
3.
4. **def** parking(low, high):
5. **if** high - low \< 1:
6. **return** 0
7. **else**:
8. x = random.uniform(low, high - 1)
9. **return** parking(low, x) + 1 + parking(x + 1, high)
10. **print** parking(0, 5)
\>递归的优劣
\>\>能使一个蕴含递归关系而且结构复杂的程序简洁精练,增强可读性
\>\>嵌套层次深,函数调用开销大,存在大量的重复计算
\>补充琐碎知识
> random.uniform(low, high) 能产生从low到high的随机数

View File

@@ -0,0 +1,54 @@
csv 模块
逗号分隔值Comma-Separated ValuesCSV有时也称为字符分隔值因为分隔字符也可以不是逗号其文件以纯文本形式存储表格数据数字和文本。 纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。
>>> with open('test.csv', 'wt') as f:
... writer = csv.writer(f) # 把文件对象传给 csv.writer()
... writer.writerow(('ID', '用户', '类型')) # 写入标题
... for i in range(5):
... row = (i, f'用户{i}', f'类型{i}')
... writer.writerow(row)
In: cat test.csv
Out:
ID,用户,类型
0,用户0,类型0
1,用户1,类型1
2,用户2,类型2
3,用户3,类型3
4,用户4,类型4
>>> with open('test.csv', 'rt') as f:
... reader = csv.reader(f)
... for line in reader:
... print(line)
# 输出:
['ID', '用户', '类型']
['0', '用户0', '类型0']
['1', '用户1', '类型1']
['2', '用户2', '类型2']
['3', '用户3', '类型3']
['4', '用户4', '类型4']
>>> with open('test.csv', 'rt') as f:
... reader = csv.DictReader(f) # 键为第一行写入的键名, 值是对应的字段的值
... for line in reader:
... print(line)
... print(line['类型'])
# 输出:
OrderedDict([('ID', '0'), ('用户', '用户0'), ('类型', '类型0')])
类型0
OrderedDict([('ID', '1'), ('用户', '用户1'), ('类型', '类型1')])
类型1
OrderedDict([('ID', '2'), ('用户', '用户2'), ('类型', '类型2')])
类型2
OrderedDict([('ID', '3'), ('用户', '用户3'), ('类型', '类型3')])
类型3
OrderedDict([('ID', '4'), ('用户', '用户4'), ('类型', '类型4')])
类型4
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

View File

@@ -0,0 +1,169 @@
logging 模块
在代码中使用 print() 打印输出是临时性的调试用途的方案。如果希望在线上记录应用日志或者错误日志等, 可以使用 Python 自带的日志模块 logging。
常用的日志记录类型有两种, 一种是写到文件里面, 另外一种是终端输出。日志文件存储下来是为了未来回溯的方便, 终端输出是以便于实时查看。
logging 模块自带了 6 种级别的日志类型。级别如下(变量值越高说明级别越高):
日志级别
变量值
CRITICAL
50
ERROR
40
WARNING
30
INFO
20
DEBUG
10
NOTSET
0
In: import logging
In: logging.warning('Watch out!')
Out: WARNING:root:Watch out!
In: logging.debug("This message won't be printed")
# 无输出
In: logging.basicConfig(level=logging.WARNING) # 使用 basicConfig() 指定默认的日志级别
# getLogger() 自定义 logger 实例, 不同的项目会有自己固定的 logger, 如果能找到 logger 的名字, 就能拿到对应日志的实例
In: logger1 = logging.getLogger('package1.module1')
In: logger2 = logging.getLogger('package1.module2')
In: logger1.warning('This message comes from module1')
Out: WARNING:package1.module1:This message comes from module1
In: logger2.warning('This message comes from module2')
Out: WARNING:package1.module2:This message comes from module2
In: logger2.debug("This message won't be printed")
# 无输出
把日志写入文件
import logging
logging.basicConfig(filename='myapp.log',
level=logging.INFO) # 日志文件为 myapp.log, 级别是 INFO
logging.info('Started') # 写入一行 INFO 的日志 Started
print(logging.root.handlers) # 日志的处理器。root 是默认的一个 logger, 也就是日志实例, 否则得使用 getLogger() 的方式去获得一个 Logger 实例
> python loging_to_file.py
[<FileHandler /home/jiangyanglinlan/myapp.log (NOTSET)>]
> cat myapp.log
INFO:root:Started
最佳使用 logging 的方案
In : import logging
...:
...: logger = logging.getLogger() # 获得一个 logger 的实例
...: handler = logging.StreamHandler() # 实例化 logging 模块自带的 handler
...: formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') # 定制日志格式, name 为 logger 的名字(默认是 root), levelname 为日志的级别, message 是对应的日志内容
...: handler.setFormatter(formatter) # 设置 formatter
...: logger.addHandler(handler) # 给 logger 添加 handler
...: logger.setLevel(logging.DEBUG) # 设置 logger 的级别
...: logger.debug('This is a %s', 'test')
...:
DEBUG:root:This is a test
2018-04-02 18:34:08,443 root DEBUG this is a tes
logging 模块内置日志格式
格式
说明
%(name)s
生成日志的Logger名称。
%(levelno)s
数字形式的日志级别包括DEBUG, INFO, WARNING, ERROR和CRITICAL。
%(levelname)s
文本形式的日志级别包括DEBUGINFOWARNINGERRORCRITICAL
%(pathname)s
输出该日志的语句所在源文件的完整路径(如果可用)。
%(filename)s
文件名。
%(module)s
输出该日志的语句所在的模块名。
%(funcName)s
调用日志输出函数的函数名。
%(lineno)d
调用日志输出函数的语句所在的代码行(如果可用)。
%(created)f
日志被创建的时间UNIX标准时间格式表示从1970-1-1 00:00:00 UTC计算起的秒数。
%(relativeCreated)d
日志被创建时间与日志模块被加载时间的时间差,单位为毫秒。
%(asctime)s
日志创建时间。默认格式是 “2003-07-08 16:49:45,896”逗号后为毫秒数。
%(msecs)d
毫秒级别的日志创建时间。
%(thread)d
线程ID(如果可用)。
%(threadName)s
线程名称(如果可用)。
%(process)d
进程ID(如果可用)。
%(message)s
日志信息。
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

View File

@@ -0,0 +1,149 @@
os 模块
os 模块中主要包含创建和管理进程或者文件系统内容(比如文件和目录)的函数, os 模块为平台特定的一些模块做了包装, 使得所有平台访问的函数接口相同, 这样就具备了可移植性。下面是 os 模块下一些常用的函数:
方法
说明
用法举例
os.getcwd()
获取当前所在的目录
os.getcwd()
os.chdir()
切换目录
os.chdir('..') (.. 为父级目录, 这里表示切换到上一级目录, 相当于命令行的 cd ..)
os.getenv()
获取系统变量的值(若变量不存在返回 None)
os.getenv('SHELL')
os.environ.getenv()
获取系统变量的值(若变量不存在会引发异常)
os.environ.getenv('SHELL')
os.listdir()
列出目录下的全部文件
os.listdir('dir'), 列出 dir 目录下的全部文件
os.walk()
递归地遍历指定的目录, 对于每个目录都会生成一个元组, 其中包含了目录的路径、该目录下所有的子目录以及该目录下所有文件的列表。它是一个生成器, 可以用 list() 转换成一个列表
os.walk('dir'), list(os.walk('dir'))
os.makedir()
创建一个目录, 只能创建单层目录, 若创建多层目录会报错
os.makedir('dir'), 创建一个名为 dir 的目录
os.makedirs()
创建多层目录
os.makedirs('/dir2/dir3')
os.remove()
删除指定文件
os.remove('1.txt'), 删除当前目录下的 1.txt 文件
os.rmdir()
删除目录
os.rmdir('dir1'), 删除当前目录下的 dir 目录
os.rename()
重命名文件或者目录
os.rename('dir2', 'dir1'), 将 dir2 目录重命名为 dir1
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
os.path 模块、
os 模块下有一个独有的 path 子模块, 可以使用 os.path.函数名字 的方式调用, 也可以 import os.path。os.path 模块是和路径有关的。下面是此模块下一些常用的函数:
方法
说明
os.path.basename()
获得指定文件路径的文件名字
os.path.dirname()
获得文件路径的目录名字
os.path.exists()
判断文件或者目录是否存在
os.path.isdir()
判断指定路径是否是目录
os.path.isfile()
判断指定路径是否是文件
os.path.join()
拼接路径
os.path.split()
路径拆分
os.path.splitext()
获得路径的后缀
In: import os
In: p = '/home/jiangyang/a.txt'
In: os.path.basename(p) # 获得指定文件路径的文件名字
Out:
a.txt
In: os.path.dirname(p) # 获得文件路径的目录名字
Out:
/home/ubuntu
In: os.path.join('\\Users', 'jiangyang', 'flask\\app.py') # windows 下
Out:
\Users\jiangyang\flask\app.py
In: os.path.join('/Users', 'jiangyang', 'flask/app.py') # Ubuntu 下
Out:
/Users/jiangyang/flask/app.py
In: os.path.split(p) # 路径拆分
Out:
('/home/ubuntu', 'a.txt')
In: os.path.splitext(p) # 获得路径的后缀
Out:
('/home/ubuntu/a', '.txt')
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

View File

@@ -0,0 +1 @@
>> 实现文件读写

View File

@@ -0,0 +1,65 @@
datetime 模块
datetime 模块用来完成日期和时间的解析、格式化和算术运算等。
In: import datetime
In: now = datetime.datetime.now() # 获取当前时间
In: now
Out: datetime.datetime(2018, 4, 14, 21, 49, 7, 733048)
In: now.year, now.month, now.day, now.hour, now.minute
Out: (2018, 4, 14, 21, 49)
In: today = datetime.date.today()
In: today
Out: datetime.date(2018, 4, 14)
In: today.year, today.month, today.day
Out: (2018, 4, 14)
In: d1 = datetime.date(2010, 9, 1)
In: d1
Out: datetime.date(2010, 9, 1)
# 可以使用 datetime.timedelta 对象进行时间的运算, 支持秒、分钟、小时、天、周
In : print('seconds :', datetime.timedelta(seconds=1))
...: print('minutes :', datetime.timedelta(minutes=1))
...: print('hours :', datetime.timedelta(hours=1))
...: print('days :', datetime.timedelta(days=1))
...: print('weeks :', datetime.timedelta(weeks=1))
...:
Out:
seconds : 0:00:01
minutes : 0:01:00
hours : 1:00:00
days : 1 day, 0:00:00
weeks : 7 days, 0:00:00
In: hour = datetime.timedelta(hours=1)
In: hour.total_seconds
Out: <built-in method total_seconds of datetime.timedelta object at 0x0000028F5609F418>
In hour.total_seconds() # 获得一个小时的秒数
Out: 3600.0
In: today = datetime.date(2010, 9, 1)
In: today + datetime.timedelta(days=1) # 加上一天
Out: datetime.date(2010, 9, 2)
In: today - datetime.timedelta(days=1) # 减去一天
Out: datetime.date(2010, 8, 31)
时间格式化
In: dt_format = '%Y-%m-%d %H:%M:%S'
In: s = datetime.datetime.now().strftime(dt_format)
In: print('strftime:'s)
Out: strftime: 2018-04-14 22:17:27
In: d = datetime.datetime.strptime(s, dt_format)
In: print('strptime:', d)
Out: strptime: 2018-04-14 22:17:27
In: d
Out: datetime.datetime(2018, 4, 14, 22, 17, 27)
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

View File

@@ -0,0 +1,104 @@
sys 模块
sys 模块提供了特定系统的配置和操作。
方法
说明
sys.platform
用来构建解释器的操作系统平台
sys.version
构建时的版本信息, 包含完整的版本号和构建日期、编译器、平台信息等
sys.version_info
同样是版本信息, 但不是字符串, 可以直接获得对应类型版本的信息
sys.path[0]
搜索模块的路径列表
sys.modules.get()
已经导入的模块列表
sys.getrefcount()
查看对象的引用计数
sys.getsizeof()
以字节byte为单位返回对象大小。这个对象可以是任何类型的对象。 所以内置对象都能返回正确的结果 但不保证对第三方扩展有效,因为和具体实现相关。
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
sys.getrefcount
Python 使用引用计数和垃圾回收来完成字段的内存管理, 当一个对象的引用数降为 0, 就会自动标记为回收。在实际开发中, 可能因为 debug 或者调试的需要, 需要了解引用计数, 就可以使用 sys.getrefcount()。
import sys
d = []
print(sys.getrefcount(d))
# 输出 2
x = d
print(sys.getrefcount(d))
# 输出 3
del x
print(sys.getrefcount(d))
# 输出 2
上面的计数比预期多一个, 是因为 getrefcount() 本身也会维护一个临时引用。
sys.getsizeof
了解对象的引用计数不足以发现内存泄漏, 可以使用 sys.getsizeof 辅助, 这样可以确定对象消耗内存的情况。
# 打印 Python 内置数据结构占用的字节数
for obj in ({}, [], (), 'string', 1, 12.3):
print(obj.__class__.__name__, sys.getsizeof(obj))
# 输出:
dict 240
list 64
tuple 48
str 55
int 28
float 24
命令行参数 sys.argv
在命令行下运行一个 Python 程序, 可以通过 sys.argv 获取脚本的名字和参数。有个 argv.py, 代码如下:
import sys
script_name, *args = sys.argv
print(f'Script: {script_name}')
print(f'Arguments: {args}')
> python argv.py
Script: argv.py
Arguments: []
> python argv.py -v
Script: argv.py
Arguments: ['-v']
> python argv.py -v -v -e 'foo'
Script: argv.py
Arguments: ['-v', '-v', '-e', "'foo'"]
作者:江洋林澜
链接https://www.jianshu.com/p/87a40fbac17f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

View File

@@ -0,0 +1,46 @@
## 基础篇
> 主要讲解了关系数据库的理论知识,和作为单个数据库内部的结构。
### 1. 数据模型和系统结构
### 2. 关系运算
### 3. 数据类型说明
### 4. SQL
### 5. 完整性约
### 6. 安全性
### 7. 断言和触发器
## 设计篇
> 主要讲解了如何设计数据库,在面对具体的问题时,处理问题的过程。
### 1. 规范化
> 1NF,2NF,3NF,4NF
### 2. 设计步骤
> 需求分析,概念设计,逻辑设计,物理设计
### 3. 编程(未讲)
## 系统篇
> 主要讲解了数据库如何应用。在应用过程中面临的问题和解决的办法。
### 1. 查询处理和查询优化
### 2. 并发控制
### 3. 数据库管理系统(未讲)
## 新技术篇
### 1. 数据库发展过程
### 2. 大数据管理
### 3. 内存数据库系统

View File

@@ -0,0 +1,99 @@
\>创建数据库
CREATE {DATABASE \| SCHEMA} [IF NOT EXISTS]db_name] [DEFAULT CHARACTER SET =
'GBK']
创建数据库的或者图表类型选择 —— 可选参数,表示如果不存在时创建 —— 默认编码方式
\>查看数据库
SHOW WARNINGS; 显示警告
SHOW DATABASES;查看数据存在的
SHOW CREATE DATABASE;查看数据库的定义信息
\>修改指定数据库的编码方式
ALTER {DATABASE\|SCHMA}db\_name [DEFAULT CHARACTER SET = 'GBK'];
\>打开指定数据库
USE db_name; 打开的数据库名称
SELECT DATABASE\|SCHEMA();查看当前打开的而数据库名称
\>删除指定的数据库
DROP {DATABASE\|SCHEMA}[IF NOT EXISTS] db_name
\>数据表的相关操作
\>\>定义
数据表用来存储数据的结构
由行和列构成的二维网络
\>\>创建数据表
CREATE TABLE [IF NOT EXISTS] tbl_name(字段名称 字段类型[完整约束条件])ENGINE =
引擎名称 CHARSET = 编码方式;
\>\>数据类型补充
TINYINT-SMALLINT- MEDIUMAINT- INT- BIGINT- BOOL,BOOLEAN
字节数分别是1-2-3-4-8-1
\>\>浮点类型补充
FLOAT[(m,d)]
double[(m,d)]
decemal[m,d]
\>\>字符串类型
CHAR(M) M带变得存放的字符数定长字符串
VARCHAR(M) 变长字符串
TEXT
SET("value","value")集合类型
ENUM("value","value")枚举类型
\>\>日期时间类型
TIME存储时间
DATE存储
DATETIME存储时间日期
TIMESTAMP存储时间戳
YEAR存储年份
\>\>二进制类型
图片或者视频的二进制码
\>存储引擎简介
\>\>指表的类型,表在计算机中怎样存储
\>\>存储引擎:
SHOW ENGINES;
SHOW VARIABLES LIKE'storage_engin';
InnoDB 支持外接,存储.fim中读写效率地占用空间大
MyISAM 索引 结构 数据在三个文件中,占用空间小,快,但不支持事务
MEMORY 存储在内存中的内容创建表,对应磁盘文件,对磁盘快速处理。

View File

@@ -0,0 +1,22 @@
**\>数据库注册表修改心得**
几个月前跟随导员用xampp做的集成开发环境进行Apache服务器上的php网站开发项目
近几日大作业老师要求使用深喉咙的php继承开发环境结果现在的mysql像来了大姨妈一样不听话各种出错
\>\>端口冲突:
由于xampp深喉咙加上我自己的电脑总共装了三个版本的mysql导致端口占用等问题时有发生所以吧xampp和深喉咙的mysql直接删掉反而不能启动了
\>\>注册表修改:
后来发现深喉咙自动修改了注册表原来一直启动的并不是电脑上的mysql而是深喉咙自带的mysql修改注册表。
http://jingyan.baidu.com/article/91f5db1bd298ed1c7f05e315.html
\>\>但是登录的时候报了一个奇怪的错误,
mysqlnd cannot connect to MySQL 4.1+ using the old insecure
authentication后来查证是因为前不久不小心更新了xampp导致数据库中原来密码出现问题密码格式不能被新版的phpmyadmin解析于是看教程经过PASSWORD()函数修改原来的16位密码为41位更加安全的密码。
最终运行成功!

View File

@@ -0,0 +1,201 @@
系列一数据库数据表的创建等基本操作
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52027858)
[copy](http://blog.csdn.net/estom_yin/article/details/52027858)
1. \#注释内容与python很像
2. \-- 也为注释内容
3. \-- 创建一个数据库
4. **CREATE** **DATABASE** IF NOT EXISTS maizi **DEFAULT** **CHARACTER**
**SET** 'utf8';
5.
6. USE maizi;
7.
8. **SET** NAMES GBK;
9.
10. \--创建数据表user
11. \--编号id
12. \--用户名usename
13. \--性别sex
14. \--邮箱email
15. \--地址addr
16. \--生日birth
17. \--薪水salary
18. \--电话tel
19. \--是否结婚married
20. \--当需要中文的时候,需要临时转换客户端的编码方式
21. \--SET NAMES GBK;
22. \--字段注释通过comment注释内容给字段添加注释。
23.
24. **CREATE** **TABLE** IF NOT EXISTS first\_table(
25. id **SMALLINT**,
26. usename TINYINT,
27. age TINYINT,
28. email **VARCHAR**(50),
29. addr **VARCHAR**(200),
30. birth YEAR,
31. salary **FLOAT**(8,2),
32. tel **INT**,
33. married TINYINT(1) COMMENT '0代表未结婚非零代表结婚'
34. )ENGINE=innoDB CHARSET=UTF8;
35.
36. SHOW TABLES;
37.
38. \--创建一个课程表course
39. \--编号cid
40. \--课程名称 courseName
41. \--课程描述 courseDesc
42.
43. **CREATE** **TABLE** IF NOT EXISTS course(
44. cid TINYINT,
45. courseName **VARCHAR**(50),
46. courseDesc **VARCHAR**(200)
47. );
48.
49. SHOW TABLES;
50.
51. \--作业
52. \--创建新闻类表
53. \--创建新闻表
54.
55.
56.
57. \# 第八课时数据测试
58.
59. \--查看表的表结构
60. **DESC** tbl_name
61. DESCRIBE tbl_name
62. SHOW COLUMNS **FROM** tbl_name
63.
64. \--测试数据的越界处理
65. **CREATE** **TABLE** test1(
66. num1 TINYINT,
67. num2 **SMALLINT**,
68. num3 MEDIUMINT,
69. NUM4 **INT**,
70. NUM5 **BIGINT**
71. );
72. \--向表中插入记录INSERT tbl_name VALUE\|VALUES(值,...);
73. **INSERT** test1 **VALUES**(-128,-32768,0,-2147483648,0);
74. \--查询表中所有记录SELECT \* FORM tbl_name;
75. **SELECT** \***FROM** test1;
76.
77.
78. \--测试数据填充
79. **CREATE** **TABLE** test3(
80. num1 TINYINT ZEROFILL,
81. num2 **SMALLINT** ZEROFILL,
82. num3 MEDIUMINT ZEROFILL,
83. num4 **INT** ZEROFILL,
84. num5 **BIGINT** ZEROFILL
85. );
86. **INSERT** test3 **values**(1,1,1,1,1);
87.
88.
89. \--测试浮点类型
90. \--定点数内部以字符串形式保存
91. **CREATE** **TABLE** test4(
92. num1 **FLOAT**(6,2),
93. num2 **DOUBLE**(6,2),
94. num3 **DECIMAL**(6,2)
95. );
96. **INSERT** test4 **VALUES**(3.1415,3.1415,3.1415);
97. **SELECT** \* **FROM** test4;
98. **SELECT** \* **FROM** test4 **WHERE** num2 = 3.14;

View File

@@ -0,0 +1,194 @@
系列七高级的查询功能
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028845)
[copy](http://blog.csdn.net/estom_yin/article/details/52028845)
1. \#第三十一课时
2. \--分组查询GROUP BY
3.
4. \--按照用户所属省分进行分组
5. **SELECT** \* **FROM** cms_user **GROUP** **BY** proId;
6.
7. \--按照字段位置进行分组
8. **SELECT** \* **FROM** cms_user **GROUP** **BY** 7;
9.
10. \--按照多个字段进行分组
11. **SELECT** F **FROM** cms_user **GROUP** **BY** sex,proId;
12.
13. \--先写条件,后对满足条件的记录进行分组
14. **SELECT** \* **FROM** cms_user **WHERE** id \> 5 **GROUP** **BY** sex;
15.
16.
17. \#第三十二课时
18. \--分组查询配合聚合函数
19. \--配合GROUP_CONCAT()函数进行使用
20. \--查询idsexusername的详情 按照性别分组
21. \--通过性别分组分组后得到username的分组详情
22. **SELECT** id, sex, GROUP\_CONCAT(username) **FROM** cms_user **GROUP**
**BY** sex;
23.
24. \--查询ProID性别详情注册时间详情用户名详情 按照ProID进行分组
25. **SELECT** proId
,GROUP\_CONCAT(username),GROUP_CONCAT(sex),GROUP_CONCAT(regTime) **FROM**
cms_user **GROUP** **BY** proId;
26.
27. \--常见的聚合函数
28. COUNT()
29. **MAX**()
30. **MIN**()
31. AVG()
32. SUM()
33. \--查询编号sex用户名详情以及组中总人数按照sex分组
34. **SELECT** id,sex,GROUP_CONCAT(username)**AS** user ,COUNT(\*)**AS**
totalUsers **FROM** cms_user **GROUP** **BY** sex;
35. \--COUNT(字段)不统计NULL值
36. **SELECT** COUNT(id) **AS** totalUsers **FROM** cms_user;
37.
38. \--查询编号sex用户名详情以及组中总人数组中最大年龄最小年龄平均年龄年龄总和按照sex分组
39. **SELECT** id,sex,GROUP_CONCAT(username),
40. COUNT(\*) **AS** totalUsers,
41. **MAX**(age) **AS** max_age,
42. **MIN**(age) **AS** min_age,
43. AVG(age) **AS** avg_age,
44. SUM(age) **AS** sum_age
45. **FROM** cms_user **GROUP** **BY** sex;
46.
47.
48. \--配合WITH ROLLUP记录上面所有记录的总和
49. \--在末尾加上WITH ROLLUP 属于聚合统计次字段的总的内容
50.
51. **SELECT** id,sex,
52. COUNT(\*) **AS** totalUsers,
53. **MAX**(age) **AS** max_age,
54. **MIN**(age) **AS** min_age,
55. AVG(age) **AS** avg_age,
56. SUM(age) **AS** sum_age
57. **FROM** cms_user **GROUP** **BY** sex **WITH** **ROLLUP**;
58.
59.
60. \#第三十三课时
61. \--having语句对分组结果进行二次筛选
62. **SELECT** id,sex,GROUP_CONCAT(username),
63. COUNT(\*) **AS** totalUsers,
64. **MAX**(age) **AS** max_age,
65. **MIN**(age) **AS** min_age,
66. AVG(age) **AS** avg_age,
67. SUM(age) **AS** sum_age
68. **FROM** cms_user **GROUP** **BY** sex
69. **HAVING** COUNT(\*)\>2 AND **MAX**(age)\>60;
70.
71. \#第三十四课时
72. \--ORDER BY 对查询结果进行排序;
73.
74. \--查询按照id降序进行排列DESC /ASC
75. **SELECT** \* **FROM** cms_user **ORDER** **BY** id **ASC**;
76.
77. \--按照多个字段进行排序
78. **SELECT** \***FROM** cms_user **ORDER** **BY** age **ASC** ,id **DESC**;
79.
80. \--实现随机提取记录
81. **ORDER** **BY** RAND();
82.
83. \#第三十五课时
84. \--通过limit限制显示条数
85. \--LIMIT 显示条数
86. \--LIMIT偏移量显示条数
87.
88. \--查询表中前三条记录
89. **SELECT** \* **FROM** cms_user LIMIT 3;
90.
91. **SELECT** \* **FROM** cms_user **ORDER** **BY** id **DESC** LIMIT 5;
92.
93. **SELECT** \* **FROM** cms_user LIMTI 10, 5;

View File

@@ -0,0 +1,177 @@
系列三完整性约束条件
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028722)
[copy](http://blog.csdn.net/estom_yin/article/details/52028722)
1. \#第十二课时测试主键长度
2.
3. \--完整性约束条件
4. \--PRIMARY KEY 主键,不能重复,非空,无意义字段,
5. \--AUTO_IINCREMENT
6. \--FOREIGN KEY
7. \--NOT NULL
8. \--UNIQUE KEY
9. \--DEFAULT
10.
11. \--的是主键
12.
13. **CREATE** **TABLE** IF NOT EXISTS USER1(
14. id **INT** **PRIMARY** **KEY**,
15. username **VARCHAR**(20)
16. );
17.
18. \--查看创建表的定义
19. SHOW **CREATE** **TABLE** user1;
20.
21. **INSERT** user1 **VALUES**(1,'king')
22. **INSERT** user1 **VALUES**(2,'quee')
23.
24. **CREATE** **TABLE** IF NOT EXISTS user2(
25. id **INT**,
26. username **VARCHAR**(20),
27. card **CHAR**(18),
28. **PRIMARY** **KEY**(id, card)
29. );
30.
31. **INSERT** user2 **values**(1,'king','111');
32. **INSERT** user2 **values**(1,'queue','112');
33.
34. \#第十三课时自增长
35. \--AUTO_INCREMENT,对象一定是主键,在已有的最大主键上+1
36. \--测试自增长
37. **CREATE** **TABLE** IF NOT EXISITS user5(
38. id **SMALLINT** **KEY** AUTO_INCREMENT,
39. username **VARCHAR**(20)
40. );
41.
42. \--指定位置插入值
43. **INSERT** user5(username) **VALUES**('queue');
44.
45. **INSERT** user5 **VALUES**(DEFUALT,'HAHA')
46.
47. **INSERT** user5 **VALUES**(null,'HAHA')
48.
49. \--修改自增长的起始值
50. **ALTER** **TABLE** user6 AUTO_INCREMENT = 500;
51.
52. \#第十四课时非空约束
53. \--NOT NULL 非空
54. \--测试非空
55. **CREATE** **TABLE** IF NOT EXISTS user7(
56. id **INT** UNSIGNED **KEY** AUTO_INCREMENT,
57. username **VARCHAR**(20) NOT NULL,
58. **password** **CHAR**(32)NOT NULL,
59. age TINYINT UNSIGNED
60.
61. );
62. **INSERT** user7(username,**password**) **VALUES**('KING1','KINGJ',12)
63.
64. \#第十五课时默认值
65. \--DEFAULT配合NOT NULL使用
66. **CREATE** **TABLE** IF NOT EXISTS user8(
67. id **INT** UNSIGNED **KEY** AUTO_INCREMENT,
68. username **VARCHAR**(20) NOT NULL,
69. **password** **CHAR**(32)NOT NULL,
70. age TINYINT UNSIGNED **DEFAULT** 18,
71. addr **VARCHAR**(50) NOT NULL **DEFAULT** 'BEIJING'
72.
73. );
74.
75. \#唯一性约束条件
76. \--UNIQUE KEY唯一
77. **CREATE** **TABLE** IF NOT EXISTS user9(
78. id TINYINT UNDIGNED **KEY** AUTO_INCREMENT,
79. username **VARCHAR**(20) NOT NULL **UNIQUE**,
80. card **CHAR**(17) **UNIQUE**
81. );
82. \--NULL值不算重复
83.
84. **CREATE** TABEL [IF NOT EXISTS] tbl\_name(
85. 字段名称 字段类型 [unsigned\|zerofill] [**default** 默认这][not null]
[[**primary**]**KEY**\|**UNIQUE**[**KEY**]]
86. )ENGINE = INNODB CHARSET = UTF8 AUTO_INCREMENT = 100;

View File

@@ -0,0 +1,269 @@
系列九外键的相关操作
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028868)
[copy](http://blog.csdn.net/estom_yin/article/details/52028868)
1. \#第三十九课时
2. \--外键操作
3. \--作用:保证数据的一致性和完整性
4.
5. \--外键是表的一个特殊字段。被参照的表是主表,外键所在的字段的表为字表,是指外键的原则需要记住
6. \--就是依赖于数据库中已存在的表的主键。外间的作用时间里该表与其附表的关联关系,
7. \--附表中对记录做操作时,子表中与之对应的信息也应该有相应的改变。
8.
9. \--可以实现一对一或一对多的关系
10. \--父表和子表必须使用相同的存储引擎,而且禁止使用临时表
11. \--数据表的存储引擎智能为innodb
12. \--外键列和参照列必须具有相似的数据类型。其中数字的长度或是否为有符号位必须相同;而字符长度可以不同
13. \--外键列和参照列必须创建索引。如果外键列不存在索引的话MySQL自动创建索引
14.
15.
16.
17. \--实践操作,创建部门表(主表)
18. **CREATE** **TABLE** IF NOT EXISTS department (
19. id TINYINT UNSIGNED AUTO_INCREMENT **KEY**,
20. depName **VARCHAR**(20) NOT NULL **UNIQUE**
21.
22. )ENGINE = INNODB;
23.
24. **INSERT** department(depName)**VALUES**('teach'),
25. ('market'),
26. ('undergo'),
27. ('watch');
28.
29.
30. \--创建员工表(字表)
31. **CREATE** **TABLE** IF NOT EXISTS employee(
32. id **SMALLINT** UNSIGNED AUTO_INCREMENT **KEY**,
33. username **VARCHAR**(20) NOT NULL **UNIQUE**,
34. depId TINYINT UNSIGNED
35. )ENGINE = INNODB;
36.
37. **INSERT** employee(username ,depId)**VALUES**('kin',1),
38. ('joe',2 ),
39.
40. ('est',3),
41. ('bob',4),
42. ('tom',5);
43.
44. \--内连接实现
45. **SELECT** e.id,e.username,d.depName **FROM**
46. employee **AS** e
47. JOIN
48. department **AS** d
49. **ON** e.depId = d.id;
50.
51. \--删除watch部门,虽然部门没有了,但是子表中部门下的人仍然存在。
52. **DELETE** **FROM** department **WHERE** depName = 'watch';
53. \--所以以上内容都是不符合要求的
54. **DROP** **TABLE** department , employee;
55.
56. \--下面是通过外键常见的表
57. **CREATE** **TABLE** IF NOT EXISTS department (
58. id TINYINT UNSIGNED AUTO_INCREMENT **KEY**,
59. depName **VARCHAR**(20) NOT NULL **UNIQUE**
60.
61. )ENGINE = INNODB;
62.
63. **INSERT** department(depName)**VALUES**('teach'),
64. ('market'),
65. ('undergo'),
66. ('watch');
67.
68.
69. \--创建员工表(字表)
70. **CREATE** **TABLE** IF NOT EXISTS employee(
71. id **SMALLINT** UNSIGNED AUTO_INCREMENT **KEY**,
72. username **VARCHAR**(20) NOT NULL **UNIQUE**,
73. depId TINYINT UNSIGNED
74. FOREINGN KYE(depId)**REFERENCES** department(id)
75. )ENGINE = INNODB;
76.
77. **INSERT** employee(username ,depId)**VALUES**('kin',1),
78. ('joe',2 ),
79. ('est',3),
80. ('bob',4),
81. ('tom',5);
82.
83. \--如果子表中有某个父表记录下的内容,则父表中不能执行删除操作
84. \--如果父表中没有相应的外键,子表在插入时所使用的外键超出父表所使用的范围,会报错
85.
86. \#第四十课时
87. \--添加和删除外键的操作
88.
89. \--添加外键
90. **ALTER** **TABLE** employee **DROP** **FOREIGN** **KEY** em_fk_dep;
\--em_fk_dep是外键的索引
91. \--删除外键
92. **ALTER** **TABLE** employee **ADD** CONSTRANINT emp_fk_dep **FOREIGN**
**KEY**(depId) **REFERENCES** department(id);
93.
94.
95. \--CASCADE:从附表中珊瑚或更新且自动删除或更新子表中匹配行
96. \--SET
NULL:从附表中删除或更新行并设置子表中的外键列为NULL。如果使用该选项必须保证子表列没有指定NOT
NULL
97. \--RESTRICT:拒绝对父表的删除和更新操作
98. \--NO ACTION:在MySQL中与restrict关键字相同
99.
100.
101. \--创建员工表(字表)
102. \--ON DELETE CASCADE在删除的时候是及连的
103. \--ON UPDATE CASCADE在更新的时候是及连的
104. **CREATE** **TABLE** IF NOT EXISTS employee(
105. id **SMALLINT** UNSIGNED AUTO_INCREMENT **KEY**,
106. username **VARCHAR**(20) NOT NULL **UNIQUE**,
107. depId TINYINT UNSIGNED
108. FOREINGN KYE(depId)**REFERENCES** department(id) **ON** **DELETE**
**CASCADE** ;
109. )ENGINE = INNODB;
110.
111. **INSERT** employee(username ,depId)**VALUES**('kin',1),
112. ('joe',2 ),
113. ('est',3),
114. ('bob',4),
115. ('tom',5);
116.
117. \--删除部门表中的一个部门
118. **DELETE** **FROM** department **WHERE** id = 1;
119. \--更新部门表中的数据
120. **UPDATE** department **SET** id = id = 10;
121.
122.
123. \#第四十一课时
124. \--联合查询
125. \--union 和union all
126. \--NNION 合并相同信息
127. **SELECT** username FORM employee **UNION** **SELECT** username **from**
cms_user;
128. \--UNION ALL 不合并相同信息
129. **SELECT** username FORM employee **UNION** ALL **SELECT** username **from**
cms_user;

View File

@@ -0,0 +1,206 @@
数据类型的测试
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028541)
[copy](http://blog.csdn.net/estom_yin/article/details/52028541)
1. \# 第八课时数据测试
2.
3. \--查看表的表结构
4. **DESC** tbl_name;
5. DESCRIBE tbl_name;
6. SHOW COLUMNS **FROM** tbl_name;
7.
8. SHOW **CREATE** **TABLE** tbl_name;
9.
10. \--测试数据的越界处理
11. **CREATE** **TABLE** test1(
12. num1 TINYINT,
13. num2 **SMALLINT**,
14. num3 MEDIUMINT,
15. NUM4 **INT**,
16. NUM5 **BIGINT**
17. );
18. \--向表中插入记录INSERT tbl_name VALUE\|VALUES(值,...);
19. **INSERT** test1 **VALUES**(-128,-32768,0,-2147483648,0);
20. \--查询表中所有记录SELECT \* FORM tbl_name;
21. **SELECT** \***FROM** test1;
22.
23.
24. \--测试数据填充
25. **CREATE** **TABLE** test3(
26. num1 TINYINT ZEROFILL,
27. num2 **SMALLINT** ZEROFILL,
28. num3 MEDIUMINT ZEROFILL,
29. num4 **INT** ZEROFILL,
30. num5 **BIGINT** ZEROFILL
31. );
32. **INSERT** test3 **values**(1,1,1,1,1);
33.
34.
35. \--测试浮点类型
36. \--定点数内部以字符串形式保存
37. **CREATE** **TABLE** test4(
38. num1 **FLOAT**(6,2),
39. num2 **DOUBLE**(6,2),
40. num3 **DECIMAL**(6,2)
41. );
42. **INSERT** test4 **VALUES**(3.1415,3.1415,3.1415);
43. **SELECT** \* **FROM** test4;
44. **SELECT** \* **FROM** test4 **WHERE** num2 = 3.14;
45.
46. \#第九课时测试字符串
47. \--定长字符串占用空间一定,空间大,速度快
48. \--变长字符串,空间小,速度慢
49. \--char不保存末尾的空格varchar保存末尾的空格
50. \--CONCAT(,);字符串连接函数
51. \--测试char varchar
52. **CREATE** **TABLE** IF NOT EXISTS test5(
53. str1 **CHAR**(5),
54. str2 **VARCHAR**(5)
55. );
56. **INSERT** test5 **VALUES**('1','1');
57. **INSERT** test5 **VALUES**('12345','12345');
58. **INSERT** test5 **VALUES**('123456','123456');
59.
60. **SELECT** CONCAT('-',str1),CONCAT('-',str2) **FROM** test5;
61. **SELECT** LENGTH('A')--字符串长度检测函数
62. \--text储存超长字符串。不能有默认值
63.
64.
65. \#第十课时测试枚举类型
66. **CREATE** **TABLE** IF NOT EXISTS test7(
67. sex ENUM('nan','nv','baomi')
68. );
69. **INSERT** test7 **VALUES**('nan')
70. **INSERT** test7 **VALUES**('nv')
71. **INSERT** test7 **VALUES**('baomi')
72.
73.
74. \--测试集合类型
75. **CREATE** **TABLE** IF NOT EXISTS test8(
76. fav **SET**('A','B','C','D')
77. );
78. **INSERT** test8 **VALUES**('A,C,D');
79. **INSERT** test8 **VALUES**('A,D,E');
80. **INSERT** test8 **VALUES**(15);
81. **SELECT** \* **FROM** test8;
82.
83. \#第十课时测试日期时间类型
84.
85. \---年份的测试
86.
87. **CREATE** **TABLE** IF NOT EXISTS test9(
88. birth YEAR
89. );
90. **INSERT** test9 **VALUES**(1901);
91. **INSERT** test9 **values**('2000');
92. **INSERT** test9 **VALUES**(0);
93. **INSERT** test9 **VALUES**('0');
94. **SELECT** \* **FROM** test9;
95.
96. \--time的测试
97. \--DATE
98. \--TIME
99. \--DATETIME
100. \--TIMESTTAMP
101. \--YREAR

View File

@@ -0,0 +1,117 @@
系列五 对表中数据的操作
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028812)
[copy](http://blog.csdn.net/estom_yin/article/details/52028812)
1. \#第二十四课时插入记录
2. \--插入记录的操作
3. \--不指定具体字段名的插入
4. **INSERT** [**INTO**]tbl_name **VALUES**\|VALUE(...);
5. \--列出制定字段
6. **INSERT** [**INTO**] tbl_name(字段名称,...) **VALUES**\|VALUE(...);
7. \--同时插入多条记录
8. **INSERT** [**INTO**] tbl_name [(字段名称,...)]
**VALUES**\|VALUE(...)()(...)...;
9. \--通过SET形式插入记录
10. **INSERT** [**INTO**] tbl_name 字段名称=值
11. \--将查询结果插入到表中
12. **INSERT** [**INTO**]tbl_name[(字段名称,...)]**SELECT** 字段名称
tbl_name[**WHERE** 条件]
13.
14.
15. \--插入所有的数据的一条记录
16. **INSERT** [**INTO**]user1 **VALUES**\|VALUE(1,'king',20);
17. \--插入具体字段的值的一条记录
18. **INSERT** [**INTO**] user1(username,**password**)
**VALUES**\|VALUE('a','aaa');
19. \--插入多条记录
20. **INSERT** user **VALUES**(6,'D',45),
21. (233,'FASF',45),
22. (54,'AF',84);
23. \--通过set的形式插入记录
24. **INSERT** **INTO** user **SET** id = 98 ,username ='test',**password** =
'fjie';
25. \--将查询结果插入到表中,字段数目必须匹配,格式也必须相同。
26. **INSERT** test1 **SELECT** id ,username **FROM** user1;
27.
28.
29. \#第二十五课时
30. \--更新和删除记录
31. \--有限制条件的更新记录
32. **UPDATE** tbl_name **SET** 字段名称 = 值,...[**WHERE** 条件][**ORDER**
**BY** 字段名称][LIMIT 限制条数]
33. \--有限值条件的删除记录
34. **DELETE** **FROM** tbl_name [**WHERE** 条件][**ORDER** **BY**
字段名称][LIMIT 限制条数]
35. \--清空列鬼所有的记录
36. **TRUNCATE** [**TABLE**]tbl_name
37.
38. \--示例
39. \--表单的年龄更新
40. **UPDATE** user1 **SET** age = 5;
41. \--表单的多个记录更新
42. **UPDATE** user1 **SET** age = 20,email ='123@qq.com';
43. \--表单的多个有限制条件的记录更新
44. **UPDATE** user1 **SET** **password** = 'king123',email = '123@qq.com',age =
99 **WHERE** id = 1;
45. \--用表达式表示记录的限制条件和更新的内容
46. **UPDATE** user1 **SET** age = age - 5 **WHERE** id \>= 3;
47.
48. \--删除多个记录,但是不会清空AUTO_increment的值
49. **DELETE** **FROM** user;
50. \--有条件的删除记录
51. **DELETE** **FROM** test1 **WHERE** id = 1;
52. \--truncate彻底清空数据表,包括所有的配置
53. **TRUNCATE** **TABLE** test1;

View File

@@ -0,0 +1,146 @@
系列八条件语句在各个部分的应用更新,插入,删除记录的中的数据
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028857)
[copy](http://blog.csdn.net/estom_yin/article/details/52028857)
1. \#第三十六课时
2. \--条件更新
3. **UPDATE** cms_user **SET** age = age - 3 **WHERE** username LIKE '____';
4. \--更新前三条记录,让已有年龄+10
5. **UPDATE** cms_user **SET** age = age +10 LIMIT 3;
6. \--按照id降序排列
7. **UPDATE** cms_user **SET** age = age +10 **ORDER** **BY** id **DESC** LIMIT
3;
8. \--条件删除
9. **DELETE** **FROM** cms_user **WHERE** sex = 'man' **ORDER** **BY** age
**DESC** LIMIT 3;
10.
11. \#第三十七课时
12. \--连接查询
13. \--将两个或两个以上的表按某个条件链接起来,从中个选取出需要的数据
14. \--链接插叙是同时查询两个或两个以上的表时使用的。
15. \--当不同的表中存在相同意义的字段是,可以通过该字段链接这几个表
16.
17. \--内连接查询
18. \--显示连个表中符合链接条件的记录
19. \--JOIN / CROSS JOIN / INNER JOIN
20. \--通过on连接条件
21.
22. \--查询cms_user表中idusername
23. \--查询provinces表中proName
24. **SELECT** cms_user.id ,username ,proName **FROM** cms_user,provinces;
25. \--并不能实现想要的目的
26.
27.
28. \--cms_user的ProId对应省份表中的id,使用where第一次筛选与内连接语句是等价的
29. **SELECT** cms_user.id ,username ,proName **FROM** cms_user,provinces
30. **WHERE** cms\_user.proId = provinces.id;
31.
32. \--用内连接的方式把各个表中的相关信息统一为同一个表中的信息
33. \--查询cms_user表中的id,username,email,sex;
34. \--查询procinces表中的proName
35. **SELECT** u.id,u.username,u.email,u.sex,p.proName
36. **FROM** cms_user **AS** u
37. **INNER** JOIN provinces **AS** p
38. **ON** u.proId = p.id;
39.
40. \--通过on连接条件
41. **SELECT** u.id,u.username,u.email,u.sex,p.proName
42. **FROM** cms_user **AS** u
43. CROSS JOIN provinces **AS** p
44. **ON** u.proId = p.id;
45.
46. \--查询cms_user表中idusername,sex
47. \--查询procinces表中的proName
48. \--条件是cms_user 的性别是男的用户
49. \--根据p.proName进行分组GROUP
50. \--对分组结果进行二次筛选,跳出组中人数大于等于一的人。
51. **SELECT** u.id,u.username,u.email,u.sex,p.proName,COUNT(\*)**AS**
totalUsers
52. **FROM** cms_user **AS** u
53. JOIN provinces **AS** p
54. **ON** u.proId = p.id
55. **WHERE** u.sex = 'man'
56. **GROUP** **BY** p.proName
57. **HAVING** COUNT(\*) \>= 1
58. **ORDER** **BY** u.id **ASC**
59. LIMIT 0,2;
60.
61. \#第三十八课时
62. \--外联结查询
63. \--左外连接LEFT[OUTER]JOIN显示左全部记录及右表符合链接条件的记录
64. \--右外连接RIGHT[OUTER]JOIN显示右表全部记录及左表符合链接条件的记录
65. **SELECT** u.id,u.username,u.email,u.sex,p.proName,COUNT(\*)**AS**
totalUsers
66. **FROM** cms_user **AS** u
67. LEFT JOIN provinces **AS** p
68. **ON** u.proId = p.id;
69. \--左外连接就是一左边的表为查询主表,从左边寻找满足条件要求的项,并在右表中找到对应的数据

View File

@@ -0,0 +1,194 @@
系列六表达式与查询
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028822)
[copy](http://blog.csdn.net/estom_yin/article/details/52028822)
1. \--SELECT 之后表示要查询的字段
2. \--FROM 之后表示要查询的数据库和表的名称
3. \--WHERE
之后表示要查询的记录的描述比较运算符\<\>=NULL、范围查询的两个关键字BETWEEN/IN、模糊查询LIKE、多条件查询AND
/OR
4.
5.
6. \#第二十六课时
7. \--查询表达式完整形式
8. **SELECT** select_expr [,selext\_expr...]
9. [
10. **FROM** table_refereces
11. [**WHERE** 条件]
12. [**GROUP** **BY** {col_name\|position}[**ASC**\|**DESC**],...分组]
13. [**HAVING** 条件 对分组结果进行二次筛选]
14. [**ORDER** **BY** {col_name\|position}[**ASC**\|**DESC**],...排序]
15. [LIMIT 限制显示条数]
16. ]
17.
18. \--查询表达式完整形式
19. \--每一个表达式表示想要的一列,必须至少有一列,多个列之间用逗号分隔
20. \--\*通配符表示所有列tbl_name.\*可以表示某个表的所有列
21.
22.
23. \--从特定表中选取特定的不同的字段值进行显示
24.
25. **SELECT** \* **FROM** cms_admin;
26.
27. **SELECT** cms_admin.\* **FROM** cms_admin;
28.
29. **SELECT** id,username **FROM** cms_admin;
30.
31. \--表来自以哪个数据库中的表。
32. \--从特定的数据库中选取特定的表的特定的字段db_name.tbl_name
33. **SELECT** id ,username,role **FROM** cms.cms_admin;
34. \--字段来源于那张表
35. **SELECT** cms_admin.id,cms\_admin.username,cms_admin.role **FROM**
cms.cms_admin;
36. \--给表别名来访问会更简单一些 AS可以省略
37. **SELECT** a.username,a.id **FROM** cms_admin **AS** a;
38. \--给字段起别名
39. **SELECT** id **AS** '编号',username **AS** '用户名' role '角色' **FROM**
cms_admin;
40. \--当时别名是,显示的名称是别名
41. **SELECT** a.id **AS** id1,a.username **AS** u **FROM** cms_admin;
42.
43.
44. \#第二十七课时
45. \--带条件的查询where条件的使用,比较运算符的使用
46.
47. **SELECT** id ,uername,email **FROM** cms_user **WHERE** id = 1;
48. \--使用\<=\>检测值是否为NULL除此之外与=用法相同
49. **SELECT** \***FROM** cms_admin **WHERE** age \<=\> NULL;
50. \--使用is null或者IS NOT NULL
51. **SELECT** \***FROM** cms_admin **WHERE** age **IS** NULL;
52.
53.
54. \#第二十八课时
55. \--范围查询 BETWEEN NOT BETWEEN IN NOT IN
56. \--查询编号在3-10之间的用户
57. **SELECT** \***FROM** cms_user **WHERE** id BETWEEN 3 AND 10;
58. \--查询编号为1,3,5,7,9的数
59. **SELECT** \* **FROM** cms_user **WHERE** id IN(1,3,5,7,9)
60. \--查询ProID为1和3的用户
61. **SELECT** \* **FROM** cms_user **WHERE** proID IN(1,3)
62. \--查询用户名为kingqueen张三的记录忽略英文的大小写
63. **SELECT** \* **FROM** cms_user **WHERE** id IN('king','queen','张三')
64.
65. \#第二十九课时
66. \--模糊查询LINKE/NOT LINKE
67. \--%:代表另个一个或多个任意字符
68. \--_:代表一个人任意字符
69. \--查询姓张的用户
70.
71. **SELECT** \***FROM** cms_user **WHERE** username LIKE '%张%';
72.
73. \--查询用户命中包含in的用户
74. **SELECT** \* **FROM** cms_user **WHERE** username LIKE '%in%';
75.
76. \--查询用户名为三位的用户
77. **SELECT** \* **FROM** cms_user **WHERE** username LIKE '____';
78.
79. \--_and%同时使用
80. **SELECT** \* **FROM** cms_user **WHERE** username LIKE '_I%';
81.
82.
83. \#第三十课时
84. \--逻辑运算符与查询AND OR
85. \--查询用户名为king密码也为king
86. **SELECT** \* **FROM** cms_user **WHERE** username = 'king' AND **password**
= 'king';
87.
88. \--查询编号不大于三的变量年龄部位null的用户
89. **SELECT** \* **FROM** cms_user **WHERE** id \>= 3 AND age **IS** NOT NULL;
90.
91. \--查询编号在5\~10之间的用户或用户名为4位的
92. **SELECT** \* FROME cms_user **WHERE** id BETWEEN 5 AND 10 OR username LIKE
'____';

View File

@@ -0,0 +1,184 @@
系列十子查询 &正则表达式查询 &运算符的使用
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028886)
[copy](http://blog.csdn.net/estom_yin/article/details/52028886)
1. \#第四十二课时
2. \--子查询的使用
3. \--就是用查询的语句代替条件查询的一部分,查询嵌套
4.
5.
6. \--由[not] in 引发的子集合查询
7. **SELECT** id **FROM** department;
8. **SELECT** id ,username **FROM** employee **WHERE** depId IN(1,2,3,4)
9.
10. **SELECT** id ,username **FROM** employee **WHERE** depId IN(**SELECT** id
**FROM** department);
11.
12. \--由比较运算符引发的子查询
13. **SELECT** **level** **FROM** scholarship **WHERE** id = 1;
14. **SELECT** id,username **FROM** student **WHERE** score \>= 90;
15.
16. **SELECT** id,username **FROM** student **WHERE** score \>=(**SELECT**
**level** **FROM** scholarship **WHERE** id = 1);
17.
18. \--由[NOT]EXISTS 引发的子查询
19. **SELECT** id **FROM** department **WHERE** id = 5;
20.
21. **SELECT** id ,username **FROM** employee **WHERE** EXISTS(**SELECT** id
**FROM** department **WHERE** id = 5);
22.
23.
24. \#第四十三课时
25. \--子查询的其他形式
26. \--使用ANY/SOME/ALL 的子查询
27. \--ANY/SOME表示存在性问题
28. \--ALL 表示任意性问题
29. \--查询所有获得奖学金的人
30. **SELECT** id ,username,score **FROM** student **WHERE** score \>= ANY(SLECT
**level** **FROM** scholarship);
31.
32. \--将结果集出入到另一张表中
33. **SELECT** id ,score **FROM** student;
34.
35. **INSERT** test1(id,num)
36.
37. \--创建表的同时将查询结果插入
38. **CREATE** TABEL test2(
39. id TINYINT UNSIGNED AUTO_INCREMENT **KEY**,
40. score TINYINT UNSIGNED
41. )**SELECT** id ,score **FROM** student;
42.
43.
44.
45. \#第四十四课时
46. \--正则表达式查询
47. \--REGEXP'匹配方式'
48. \--常用的匹配方式
49. \--\^匹配字符开始的部分
50. \--&匹配字符串结尾的部分
51. \--.代表字符串中热议一个字符
52. \--[字符集合]匹配字符集合中的任意一个字符
53. \--[\^字符集合]匹配除了字符集合意外的的任意一个字符,只要含有者之外的字符的字符串都能匹配到
54. \--s1,s2,s3匹配s1,s2,s3张任意一个字符串
55. \--\*代表零个一个或着多个其前的字符
56. \--+代表1个或者多个其前的字符
57. \--STRING{N}字符出现N次
58. \--字符串{M,N }字符串至少出现M次最多N次
59.
60. \--查询用户名以t开始的用户
61. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP '\^t';
62.
63. \--查询以g结尾的用户
64. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 'g\$';
65.
66. \--
67. **SELECT** \***FROM** cms_user **WHERE** username REGEXP 'R..G';
68. \--可以用模糊查询实现相同的效果
69. **SELECT** \* **FROM** cms_user **WHERE** username LIKE 'R__G';
70.
71. \--
72. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP '[lto]';
73. \--除了字符集合内容中的内容都会出现
74. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP '[\^l]';
75. \--匹配集合中的任何一个字符串
76. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 'nf\|qu\|tf';
77. \--匹配前边的字符
78. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 'que\*';
79. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 't+';
80. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 'que{2}';
81. **SELECT** \* **FROM** cms_user **WHERE** username REGEXP 'que\*{1,3}';
82.
83. \#第四十五课时
84. \--MySQL中运算符的使用
85. \--算数运算符+ - \* / div %
86. \--比较运算符\> \< = != \<=\>(检测是否为null) IS NULL NOT BETWEEN AND OR IN
87. \--逻辑运算符&& AND \|\| OR ! NOT XOR
88. \--运算符的优先级

View File

@@ -0,0 +1,200 @@
系列十一函数与表达式的应用
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028917)
[copy](http://blog.csdn.net/estom_yin/article/details/52028917)
1. \#第四十六课时
2. \--数学函数库中的函数
3. CEIL()--进一取整
4. FLOOR()--舍一取整
5. MOD()--取余数
6. POWER()--幂运算
7. ROUND()--四舍五入
8. **TRUNCATE**()--数字截取
9. ABS()--取绝对值
10. PI()--圆周率
11. RAND()--返回0\~1之间的随机数
12. SIGN()--返回x的符号
13. EXP()--计算e的几次方
14.
15.
16.
17. \#第四十七课时
18. \--字符串函数库
19. \--CHAR_LENGTH(S)返回字符串的字符数
20. \--length()返回字符串的长度
21. \--concat(s1,s2...)将字符串合并成为一个字符串
22. \--CONCAT_WS(X,S1,S2...)指定分隔符连接字符串
23. \--UPPER(S)/UCASE(S)将字符串转换为大写
24. \--LOWER(S)LCASE(S)将字符串转换为小写
25. \--LEFT(S,N)/RIGHT(S,N)返回字符串前或后n个字符
26. \--LPAD(S1LEN,S2)/RPAD(S1LEN,S2)将字符串S1用S2填充到制定的LEN.
27.
28. \--LTRIM(S)/RTRIM(S)/TRIM(S)去掉字符串中的空格
29. \--TRIM(S1 FROM S)去掉字符串s中开始处和结尾处的字符串
30. \--REPEAT(S,N)重复字符串指定次数
31. \--SPACE(N)返回N个空格
32. \--REPLACE(S,S1S2)将字符串s中搜索s1替换成s2
33. \--STRCMP(S1,S2)比较字符串,\>=\<分别返回1,0-1不区分大小写
34. \--SUBSTRING(S,N,LEN)截取字符串
35. \--REVERSE(S)反转字符串
36. \--ELT(N,S1,S2...)返回指定位置的字符串
37.
38. \#第四十八课时
39. \--日期时间函数
40. \--CURDATE(),CURRENT_DATE()返回当前的日期
41. \--CURTIME(),CURRENT_TIME()当前时间
42. \--NOW()当前的日期和时间
43.
44. \--MONTH(D)返回日期中月份的值
45. \--MONTHNAME(D)返回日期中月份的名称
46. \--DAYNAME(D)返回是星期几
47. \--DAYOFWEEK(D)返回一周内的第几天
48. \--WEEKDAY(D)返回星期
49. \--WEEK(D)一年中的低多少个星期
50.
51. \--YEAR(D)返回年份值
52. \--HOUR(T)返回小时值
53. \--MINUTE(T)返回分钟值
54. \--SECOND(T)返回秒数
55. \--DATEDIFF(D1D2)返回两个日期之间相隔的天数
56.
57. \#第四十九课时
58. \--条件判断函数和系统函数
59. \--IF (EXPR,V1V2)如果表达式成立返回结果v1否则返回V2
60. \--IFNULL(V1V2)如果v1不为空就显示v1的值否则v2
61. CASE **WHEN** exp1
62. **THEN** V1
63. [**WHEN** EXP2 **THEN** V2]
64. [**ELSE** VN]
65. **END**
66. \--case表示函数的开始end表示函数结束。如果表达式exp1成立时返回v1
67. \--否则exp2成立时返回v2一次类推知道else成立
68.
69. \--系统信息函数
70. VERSION()--返回数据可的版本号
71. CONNECTION_ID()--返回服务器的连接数
72. **DATABASE**(),**SCHEMA**()--返回当前数据库
73. USER(),SYSTEM_USER()--返回当前用户
74. CURRENT_USER()--返回当前用户
75. CURRENT_USER--返回当前用户
76. CHARSET(STR)--返回字符串str的字符集
77. COLLATION(STR)--返回字符串str的校验字符集
78. LAST_INSERT_ID()--返回最近生成的AUTO_INCREMET自增长值
79.
80. \#第五十课时
81. \--其它常用的函数
82. \--常用到的加密函数
83. MD5(STR)--信息摘要算法
84. **PASSWORD**(STR)--密码算法
85. ENCODE(str.pwd_str)--加密结果为二进制
86. DECODE(crypt_str,pwd_str)--对encode加密的的结果反向解密
87.
88. FROMAT(x,n)--将数字x进行格式化将x保留到小数点
89. ASCII(S)--返回字符串s的第一个字符的ascii码值
90. BIN(X)--返回x的二进制编码
91. HEX(X)--返回x的十六进制编码
92. OCT(X)--返回x的八进制编码
93. CONV(X,F1,F2)--将x从f1进制数编程f2进制数
94. INET_ATON(IP)--将IP地址转换为数字
95. INET_NTOA(n)--将数字转换成ip地址
96. GET_LOCT(**name**,**time**)--定义锁
97. IS_FREE_LOCK('KING')--判断锁是否存在
98. RELEASE_LOCK(**name**)--解锁

View File

@@ -0,0 +1,123 @@
系列十二索引的使用和数据库的管理
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028942)
[copy](http://blog.csdn.net/estom_yin/article/details/52028942)
1. \#第五十一课时
2. \--索引的使用
3. \--索引有一列或多了组合而成,起作用是提高对表中数据的查询速度
4. \--缺点是创建和维护索引需要耗费时间
5. \--索引可以提高查询速度,减慢写入速度
6.
7.
8. \--索引的分类bitree索引和hash索引
9. \--普通索引,类似书签 index = 索引名称[索引字段]
10. \--唯一索引unique key或者主键unique key = 索引名称{索引字段}
11. \--全文索引只支持字符串字段只能建立在全英文的内容上FULLTEXT KEY =
索引名称 索引字段
12. \--单列索引一个字段上的索引INDEX in_test1(test1)
13. \--多列索引多个字段上的索引INDEX 多列索引的名称(字段1字段2字段3...)
14. \--空间索引SPACIAL INDEX spa_test(test1);
15.
16.
17.
18.
19. \--如何创建索引
20. \--索引和索引名称不同,索引名称呢就像是某个目录的名字,叫小明索引,索引是指字段
21. \--创建表的时候创建索引
22. **CREATE** **TABLE** tbl\_name(
23. 字段名称 字段类型[完整性约束条件],
24. ...,
25. [**UNIQUE**\|FULLTEXT\|SPATIAL]**INDEX**\|**KEY**[索引名称](字段名称)
26. [(长度)][**asc**\|**desc**]
27. );
28.
29.
30. \--在已经存在的表上创建索引
31. **CREATE**[**UNIQUE**\|FULLTEXT\|SPATIAL]**INDEX** 索引名称
32. **ON** 表明{字段名称
33. [(长度)][**asc**\|**desc**]}
34. \--以 id为普通索引
35. **CREATE** **INDEX** in_id **ON** test4(id);
36.
37.
38. **ALTER** **TABLE** tbl_name **ADD** [UNIQUI\|FULLTEXT\|SPECIAL]
39. (字段名称)[(字段名称)][**ASC**\|**DESC**];
40. **ALTER** **TABLE** test4 **ADD** **INDEX** in_username(username);
41.
42.
43. \--删除索引
44. **DROP** **INDEX** 索引名称 **ON** tbl_name
45. **ALTER** tbl_name **DROP** **INDEX** 索引名称
46.
47.
48. \#第五十二课时
49. \--管理数据库
50. \--workbench
51.
52.
53. \--通过web方式控制和操作MySQL数据库
54. \--PHPmyadmin
55.
56.
57.
58.
59. \--通过客户端管理MySQL

View File

@@ -0,0 +1,291 @@
系列四数据表结构的相关操作
**[sql]** [view plain](http://blog.csdn.net/estom_yin/article/details/52028783)
[copy](http://blog.csdn.net/estom_yin/article/details/52028783)
1. \#第十七课时修改表名称
2.
3. **CREATE** **TABLE** IF NOT EXISTS user10(
4. id **SMALLINT** UNSIGNED **KEY** AUTO_INCREMENT,
5. username **VARCHAR**(20) NOT NULL **UNIQUE**,
6. **password** **CHAR**(32) NOT NULL ,
7. email **VARCHAR**(50) NOT NULL **DEFAULT** '4646546@qq.com',
8. age TINYINT UNSIGNED **DEFAULT** 18,
9. sex ENUM('man','woman','secret') **DEFAULT** 'secret',
10. addr **VARCHAR**(200) NOT NULL **DEFAULT** 'beijing',
11. salary **float**(6,2),
12. regTime **INT** UNSIGNED,
13. face **CHAR**(100) NOT NULL **DEFAULT** 'default.jpg'
14. );
15.
16. \--修改表名
17. \--ALTER TABEL tbl_name RENAME [TO\|AS] new_name;
18. \--RENAME TABLE tba\_name TO new_name;
19.
20. **ALTER** **TABLE** user10 RENAME **TO** user11;
21. **ALTER** **TABLE** user11 RENAME **AS** user10;
22. **ALTER** **TABLE** user10 RENAME user11;
23.
24. RENAME **TABLE** user11 **TO** user10;
25. RENAME **TABLE** user10 **TO** user11;
26. \--挺有意思的感觉SQL语言有点规则动作+类型+名称+附属操作
27.
28.
29. \#第十八课时添加和删除字段
30.
31. \--添加或删除字段
32. **ALTER** TABEL tbl_name **ADD** 字段名称
字段类型[完整性约束条件][**FIRST**\|**AFTER** 字段名称]
33.
34. **ALTER** **TABLE** tbl_name **DROP** 字段名称
35.
36. \--添加card字段char类型
37. **ALTER** **TABLE** user10 **ADD** card **CHAR**(18);
38. **ALTER** **TABLE** user10 **ADD** test1 **VARCHAR**(100) NOT NULL
**UNIQUE**;
39. **ALTER** **TABLE** user10 **ADD** test2 **VARCHAR**(100) NOT NULL
**UNIQUE** **FIRST**;
40. **ALTER** **TABLE** user10 **ADD** test3 **VARCHAR**(100) NOT NULL
**DEFAULT** 100 **AFTER** **password**;
41.
42. \--选中一次表完成多个操作
43. **ALTER** **TABLE** user10
44.
45. **ADD** test4 **INT** NOT NULL **DEFAULT** 123 **AFTER** **password**,
46. **ADD** test5 **FLOAT**(6,2)**FIRST**,
47. **ADD** test6 **SET**('A','V','C');
48.
49. \--删除某些字段
50. **ALTER** **TABLE** user10 **DROP** test1;
51.
52. \--删除多个字段
53. **ALTER** **TABLE** user10
54.
55. **DROP** test3,
56. **DROP** test4;
57.
58. \--批量处理添加删除操作
59. **ALTER** **TABLE** user10
60.
61. **ADD** test **INT** UNSIGNED NOT NULL **DEFAULT** 10 **AFTER** sex,
62.
63. **DROP** addr;
64.
65. \#第十九课时修改字段类型、完整性约束条件、位置和名称
66.
67. \--modify修改完整性约束条件时不能对默认值和主键进行操作。
68.
69. **ALTER** **TABLE** tbl_name **MODIFY** 字段名称
字段类型[完整性约束条件][**FIRST**\|**AFTER** 字段名称];
70.
71. **ALTER** **TABLE** tbl_name CHANGE 旧的字段名称 新的字段名称 字段类型
[完整性约束条件][**FIRST**\|**AFTER** 字段名称];
72.
73.
74. \--修改email的类型
75. **ALTER** **TABLE** user10 **MODIFY** email **VARCHAR**(200);
76. \--修改email的完整性约束条件
77. **ALTER** **TABLE** user10 **MODIFY** email **VARCHAR**(20) NOT NULL
**DEFAULT** '1651656@qq.com';
78. \--修改email的位置
79. **ALTER** **TABLE** user10 **MODIFY** email **VARCHAR**(20) **AFTER** test;
80. \--使用change更换字段的相关属性
81. **ALTER** **TABLE** user10 CHANGE test test1 **CHAR**(32) NOT NULL
**DEFAULT** '123' **FIRST**;
82.
83. \#第二十课时
84. \--添加和删除默认值
85. **ALTER** **TABLE** tbl_name **ALTER** 字段名称 **SET** **DEFAULT** 默认值;
86. **ALTER** **TABLE** tbl_name **ALTER** 字段名称 **DROP** **DEFAULT**;
87.
88. \#第二十一课时
89. \--添加主键删除主键
90. **ALTER** **TABLE** tbl_name **ADD** [**CONSTRAINT**[symbol]]**PRIMARY**
**KEY**[index_type](字段名称)
91.
92. **ALTER** **TABLE** tbl_name **DROP** **PRIMARY** **KEY**;
93.
94. \--添加单主键
95. **ALTER** **TABLE** test10 **ADD** **PRIMARY** **KEY** (id);
96. \--添加复合主键
97. **ALTER** **TABLE** test13 **ADD** **PRIMARY** **KEY**(id, card);
98. \--完整表达形式
99. **ALTER** **TABLE** test12 **ADD** **CONSTRAINT** symbol **PRIMARY** **KEY**
index_type(id);
100.
101. \#第二十二课时
102. \--添加删除唯一索引
103.
104. **ALTER** **TABLE** tbl_name **ADD** [**CONSTRAINT** [SYMPOL]] **UNIQUE**
[**INDEX**\|**KEY**][索引名称](字段名称);
105.
106. **ALTER** **TABLE** tbl_name **DROP** [**INDEX**\|**KEY**] index_name;
107.
108. \--示例
109. **ALTER** **TABLE** user12 **ADD** **UNIQUE**(usename);
110.
111. **ALTER** **TABLE** user12 **ADD** **CONSTRAINT** symple **UNIQUE** **KEY**
uni_card(card);
112.
113. LTER **TABLE** user12 **ADD** **CONSTRAINT** symple **UNIQUE** **INDEX**
uni_test1_test2(test1,test2)
114.
115. **ALTER** **TABLE** tbl_name **DROP** **INDEX** username;
116. **ALTER** **TABLE** tbl_name **DROP** **KEY** mulUni_test1_test2;
117.
118. \--修改表的存储引擎
119. **ALTER** **TABLE** tbl_name ENGINE = 存储引擎名称;
120. \--修改表的引擎为MYISAM
121. **ALTER** **TABLE** test12 ENGINE = MYISAM;
122.
123. \--设置自增长的值
124. **ALTER** **TABLE** tbl_name AUTO_INCREMEN = 值;
125. \--修改主键的自增长值为
126. **ALTER** **TABLE** user12 AUTO_INCREMENT = 100;
127.
128. \#第二十三课时
129. \--删除数据表
130. **DROP** **TABLE** user12;
131.
132. **DROP** **TABLE** IF EXISTS user11,user12,user14;
133.
134. \--在打开MySQL的同时直接打开数据表
135. mysql -uroot -p -D maizi --promot = \\d\~\\D\~\\u\~\\h
136. \--查看打开的数据库
137. **SELECT** **DATABASE**();

View File

@@ -0,0 +1,133 @@
\>定义
数据库:存储数据的仓库,为了方便数据的存储和管理
数据库系统DBS比数据库大很多由数据库、数据库管理系统、应用开发工具构成
数据库管理系统database management
system。用来定义数据库、管理和维护数据的软件。像OracleMySQL等是管理系统
\>SQL
structure query
language结构化查询语言数据库管理系统通过SQL语言来管理数据库中的数据
组成部分:
DDLdata defination
language数据定义语言定义数据库、表、视图、索引、触发器。
DMLdata manipulation
language对数据的增删改INSERT插入数据、UPDATA更新数据、DELETE删除数据
DQLdata query
language数据检索语言。用来从表中获得数据确定数据怎样在应用程序中给出。SELECT查询数据
DCLdata control
language数据控制语言主要用于控制用户访问的权限想GRANT、REVOKE、COMMIT、ROLLBACK等语句
RDBMS即关系数据库管理系统(Relational Database Management System)的特点:
- 1.数据以表格的形式出现
- 2.每行为各种记录名称
- 3.每列为记录名称所对应的数据域
- 4.许多的行和列组成一张表单
- 5.若干的表单组成databas
RDBMS术语
数据库:一些关联的表的集合
数据表:数据的矩阵。等同于简单的电子表格
列:同一类数据
行:一组相关数据,称为一个记录
冗余:存储量被数据,使系统速度更快。
主键:唯一。
外键:关联两个表
复合键:将多个列作为索引键
索引:快速访问数据库中的特殊信息。索引是对数据库表中一列或多了的值进行排序的一种结构
参照完整性:参照中不允许使用不存在的实体。意识体完整性是关系模型必须满足的完整性约束条件。
\>mysql基础命令
\>\>书写习惯
> sql语句不区分大小写
> 关键字和函数名称必须大写(习惯)
> 数据库名称、表明称、字段名称全部小写
> 引号必须补全
> 支持折行效果,一行写不完可以换行写
> 以;或者\\g为结束语句
\>\>系统命令
net start mysql 启动MySQL服务
net stop mysql 终止MySQL服务
mysql 命令
> \-u(--username)
> \-p(--password)
> \-h(hostname)localhost,127.0.0.1
> \-D 打开指定数据库
> \-P 端口号
> \--prompt=name 指定命令提示符
> \--delimiter=name 指定分隔符
> \-V--version
exit quit /q ctrl+c 退出mysql的命令
/h或help 查看帮助手册
/c 清屏命令
prompt 命令
> 直接加名称
> \\D 日期
> \\d 当前数据库
> \\h 服务器名称
> \\u 当前用户名
系统函数
> select version得到当前版本号
> select now()得到当前时间
> select user()得到当前用户
delimeter 修改命令分隔符
\\T +路径 建立输出日志
\\t 结束输出日志

View File

@@ -0,0 +1,616 @@
## 1 数据库基本对象
> sql 不提供修改模式定义和修改视图定义的操作。如果想要更改,智能删除重建。
> 数据库中操作的基本对象主要有以下内容:模式、表、视图、索引
### 1.1 基本对象概述
> 主要包括增删改。没有针对基本对象的查询。就像你会查询表中的数据,但是不会查询存在的某一张表。查询表不存在,应该是查询表中的数据。
| 操作对象 | 创建 | 删除 | 修改 |
|:-: |:-:|:-: |:-:|
|模式SCHEMA|CREATE SCHEMA|DROP SCHEMA | |
|表TABLE | CREATE TABLE | DROP TABLE|ALTER TABLE|
|视图VIEW| CREATE VIEW | DROP VIEW ||
|索引INDEX|CREATE INDEX | DROP INDEX|ALTER INDEX|
|字段COLUMN|ADD COLUMN | DROP COLUMN|ALTER COLUMN|
```
graph LR
模式Schema-->表Table
模式Schema-->视图View
表Table-->索引Index
表Table-->字段Colume
```
基本对象的创建、删除、修改。
> 其中表的修改包括对字段的增减、删除、修改等。其实我觉得这里也可以把字段看做数据库的基本对象,也有增删查改。基本对象和数据对象是相互独立的。字段作为基本对象的时候,必须指明属于哪一张表。
### 1.2 模式SCHEMA
##### 创建
```
```
##### 删除
```
```
### 1.3 表TABLE
##### 创建
```
```
##### 删除
```
```
##### 修改
```
```
### 1.4 视图VIEW
##### 视图作用
1. 能够简化用户的操作
2. 是用户能够以多种角度看待同一个数据
3. 视图对重构数据库提供了一定程度的逻辑独立性
4. 能够对机密数据提供安全保护。针对不同用户定制特定的视图隐藏不必要的信息。
5. 适当利用视图可以更清晰的表达查询。
##### 创建
```
CREATE VIEW <视图名>[列名,列名,...]
AS <子查询>
[WITH CHECK OPTION];
```
1. 单基本表视图
```
# 行列子集视图-单个基本表视图。示例(建立信息系学生的视图)
CREATE VIEW IS_Student
AS SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
[WITH CHECK OPTION];
```
> 添加WITH CHECK OPTION ,对视图进行插入、修改和删除操作时,关系数据库管理系统会自动添加 满足视图条件的内容Sdept='IS'.
2. 多基本表视图
```
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS SELECT Student.Sno,Sname,Grade
FROM Student,SC
WHERE Sdept='IS'
AND Student.Sno=SC.Sno
AND SC.Cno='1';
```
> 视图可以建立在一个或多个已经定义好的基本表或者视图上。
3. 带虚拟列的视图(带表达式的视图)
```
# 添加了虚拟的计算列
CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS SELECT Sno,Sname,2014-Sage
FROM Student;
# 使用了聚集函数
CREATE VIEW S_G(Sno,Gavg)
AS SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
```
> 总的来说由SELECT语句进行查询形成的结果都能够构成一个单一的视图。
##### 删除
```
DROP VIEW <视图名> [CASCADE]
DROP VIEW BT_S;
```
> 删除了已经建立的视图
##### 视图中的数据对象操作
> 并非对视图内数据对象进行操作,而是对基本表中的数据对象进行操作。包括增删查改。
1. 查询数据
> 对视图的查询和对基本表的查询一致
```
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
```
> 查询数据的原理过程——视图消解:对视图进行查询时,首先先进行有效性检查,检查查询中设计的表、视图是否存在;如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转化成等价的对基本表的查询,然后再执行修正了的查询。
> 视图与派生表的区别:视图一旦定义,将永久保存在数据字典中,之后的所有查询都可以直接引用该视图。派生表知识在语句执行临时定义,语句执行后,该定义被删除。
2. 插入数据
```
# 插入
INSERT INTO IS_Student
VALUES('2015','zx',20);
# 转化为
INSERT INTO Student(Sno,Sname,Sage,Sdept)
VALUES('2015','zx',20,'IS')
```
3. 删除数据
```
# 删除
DELETE FROM IS_Student
WHERE Sno='2012';
# 转化为
DELETE FROM Student
WHERE Sno='2012'
AND Sdept='IS';
```
4. 修改数据(也可以更新更新)
```
# 修改
UPDATE IS_Student
SET Sname='lc'
WHERE Sno='2012'
# 转化为
UPDATE Student
SET Sname='lc'
WHERE Sno='2012'
AND Sdept='IS';
```
5. 补充
> 对视图的更新操作不一定能够完全对应为对基本表的操作。存在其他规定来决定是否能够对基本表进行操作DB2规定
* 视图有两个以上的基本表到处的,不允许更新
* 视图中的字段有表达式或者常数不允许INSERT,UPDATE,但允许DELETE。
* 视图中的字段来自聚集函数,不允许更新
* 视图定义中含有GROUP BY子句不允许更新
* 视图中含有DISTINCT 短语不允许更新
* 视图中有嵌套查询,不允许更新
* 一个不允许更新的视图上定义的视图也不允许更新。不允许更新和不可更新,不是同一个概念。
### 1.5 索引INDEX
##### 简介
* 顺序文件上的索引:按指定属性升序或降序存储的关系。在属性上建立一个顺序索引文件,索引文件有属性值和响应的元组指针组成。
* B+树上的索引B+树的叶节点为属性值和相应的元组指针。具有动态平衡的特点。
* 散列索引:建立若干个桶,将索引属性按照其散列函数值映射到相应的桶中,同种存放索引属性值和响应的元组指针。散列索引具有查找速度快的特点。
* 位图索引:用为向量记录索引属性中可能出现的值,每个为向量对应一个可能的值。
> 特点:索引能够加快数据库查询,需要占用一定的存储空间。基本表更新后,索引也需要更新。用户不必显示地选择索引,关系数据库管理系统在执行查询时,会自动选择合适的索引作为存储路径。
##### 创建
```
CREATE [UNIQUE][CLUSTER] INDEX <索引名>
ON <表名><列名>[<次序>],...
# 实例
CREATE UNIQUE INDEX SCno ON SC(Sno,Cno DESC);
```
##### 删除
```
DROP INDEX <索引名>;
# 实例
DROP INDEX <索引名>;
```
##### 修改
```
ALTER INDEX <旧索引名> RENAME TO <新索引名>
# 实例
ALTER INDEX SCno RENAME TO SCSno
```
## 2 数据库数据对象
### 2.1 增加
1. 插入元组(一条或多条数据)
```
INSERT
INTO <TABLE> [(属性,属性)]
VALUES (值,值);
# 示例
INSERT
INTO SC(Sno,Cno)
VALUES('12214',2)
```
2. 插入子查询的结果
```
INSERT
INTO <TABLE>[(属性,属性)]
子查询
# 示例
INSERT INTO Dept_age(Sdept,Avg_age)
SELECT Sdept,AVG(Sage)
FROM Student
GROUP BY Sdept;
```
### 2.2 删除
> 这里的删除是针对数据库的数据对象而言,并非基本对象,也就是说,只删除表中的数据,表的结构并不会受到影响。
```
DELETE
FROM <TABLE>
[WHERE <条件>]
```
1. 删除某一个元组的值
```
DELETE
FROM Student
WHERE Sno='20125128'
```
2. 删除多个元组
```
DELETE
FROM SC
```
3. 带子查询的删除语句
```
DELETE FROM SC
WHERE Sno In
(SELECT Sno
FROM Student
WHERE Sdept='CS')
```
### 2.3 修改
1. 修改某一个元组的值
```
UPDATE <TABLE>
SET <列名>=<表达式>
WHERE <条件>
```
2. 修改多个元组的值
```
UPDATA Student
SET Sage=Sage+1
```
3. 带子查询的修改语句
```
UPDATE SC
SET Grade = 0
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS')
```
### 2.4 查询
##### 单表查询
1. 查询多列
```
# 指定列
SELECT sno,sname FROM Student;
# 全部列
SELECT * FROM Student;
# 计算列
SELECT Sname,2014-Sage FROM Student;
# 字符串列
SELECT Sname,'Year of Birth:',2014-Sage FROM Student;
# 函数列
SELECT LOWER(Sdept) FROM Student;
# 列别名
SELECT Sname NAME,2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT FROM Student
```
2. 查询元组
|查询条件|谓词|
|-|-|
|1). 比较|=,<,>,>=,<=,!=,<>,!>,!<,NOT+|
|2). 确定范围|BETWEEN AND,NOT BETWEEN AND|
|3). 确定集合| IN,NOT IN|
|4). 字符匹配|LIKENOT LIKE|
|5). 空值 | IS NULL,IS NOT NULL|
|6). 多重条件|AND,OR,NOT|
```
# 取消重复元组
SELECT DISTINCT Sno FROM SC;
# 满足附加条件的元组-比较
SELECT Sname FROM Student WHERE Sdept='CS'
# 确定范围
SELECT Sname,Sdept,Sage FROM Student
WHERE Sage NOT BETWEEN 20 AND 23
# 确定集合
SELECT Sname,Ssex FROM Student
WHERE Sdept IN ('CS','MA','IS');
# 字符串匹配
SELECT Sname,Sno FROM Student
ERE Sname LIKE '_阳%'
# 涉及空值的查询
SELECT Sno,Cno From SC
WHERE Grade IS NULL
# 多重条查询
SELECT Sname FROM Student
WHERE Sdept='CS' AND Sage<20
```
3. 查询排序
|关键字|含义|
|-|-|
|ASC |升序 |
|DESC| 降序|
```
# ORDER BY 排序
SELECT Sno,Grade FROM SC
WHERE Cno = '3'
ORDER BY Grade DESC;
```
> 空值的排序根据具体的系统来决定。
4. 聚集函数
|聚集函数|功能|
|-|-|
|COUNT(*)|统计数据元组个数|
COUNT(DISTINCT/All 列)|统计一列中数值的个数|
SUM(DISTINCT/All 列)|求和|
AVG(DISTINCT/All 列)|求平均值|
MAX(DISTINCT/All 列)|求最大值|
MIN(DISTINCT/All 列)|求最小值|
> 聚集函数遇到空值是出了COUNT(*)外,都跳过空值,处理非空值。
5. 分组查询
> GROUP BY 子句将查询结果按某一列或多列的值分组,值相等的为一组。
```
# 普通的分组查询
SELECT Cno,COUNT(Sno) FROM SC
GROUP BY Cno;
# 带有分组条件的分组查询
SELECT Sno FROM SC
GROUP BY Sno
HAVING COUNT(*)>3
```
> WHERE 子句作用于基本表或视图HAVING短语作用于组从中选择满足条件的组也就是分组条件。
##### 连接查询(多表查询)
> 本质上是将多个表通过一些条件拼接成一张表。
1. 等值与非等值连接查询
```
SELECT Student.*,SC.*
FROM Student, SC
WHERE Student.Sno=SC.Sno
```
> 嵌套循环连接查询的基本步骤首先扫描第一个表的第一个元组然后从头扫描SC查找满足条件的元组就进行拼接。
2. 自身连接查询
> 为自身的表取两个不同的别名。
```
SELECT first.Cno,second.Cpno
FROM Course first,Course second
WHERE first.Cpno=second.Cno;
```
3. 外连接查询
> 与等值连接不同的地方在于,有一张主表,主表中所有的元组会保留。而在等值连接中,两张表的地位是等价的,一张表中没有被连接的元素就回清除。
```
SELECT student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC on(Student.Sno=SC.Sno);
```
4. 多表连接查询
> 涉及两个或两个以上的表进行连接。我个人来说,如果嵌套查询和连接查询都能够实现时,我更喜欢连接查询。
```
SELECT Student.Sno,Sname,Cname,Grade
FROM Student,SC,Cource
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno
```
##### 嵌套查询
> 一个SELECT FROM WHERE语句成为一个查询快。将一个查询快嵌套在另一个查询块的WHERE子句或HAVING短语的条件中称为嵌套查询。用户可以用多个简单查询构造成负责的查询层层嵌套的结构化查询。
> 子查询的查询条件不依赖于父查询,称为不相关子查询。
> 子查询的查询条件依赖于父查询,称为相关子查询。相关子查询不能一次求得查询结果,内层查询依赖外层查询的值,必须在内层查询与外层查询之间反复求值。
> 有些嵌套查询可以用连接运算替代,有些事不能替代的。
1. 带有IN谓词的子查询
```
# 不相关子查询_选修了“信息系统”的学生姓名
SELECT Sno,Sname
FROM Student
WHERE Sno IN
(SELECT Sno
FROM SC
WHERE Cno IN
(SELECT Cno
FROM Course
WHERE Cname='信息系统'
)
);
```
2. 带有比较运算的子查询
```
# 相关子查询_超过自己选修课程平均成绩的课程号
SELECT Sno,Cno
FROM SC x
WHERE Grade>=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
```
3. 带有ANY、SOME、ALL谓词的子查询
> 谓词说明,都能使用聚集函数来表示。
谓词| 含义
|-|-|
>ANY |
>ALL |
<ANY |
<ALL |
>=ANY |
>=ALL |
<=ANY |
<=ALL |
=ANY |
=ALL |
!=ANY |
!=ALL |
```
```
4. 带有EXISTS谓词的子查询
> 代表存在量词,带有EXISTS谓词的子查询不反悔任何数据只产生逻辑真或假true&false。
> 一些带有EXISTS或NOT EXISTS谓词的子查询不能被其他形式的子查询等价替换但是所有带有IN谓词的、比较运算符、ANY和ALL谓词的子查询杜能用EXISTS谓词的子查询等价替换。
```
SELECT Sname
FROM Student
WHERE EXISTS
(SELSECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='1');
# 等价于
SELECT Sname
FROM Student
WHERE Student.Sno IN
(SELECT SC.Sno
FROM SC
WHERE SC.Cno='1')
```
##### 集合查询
> 因为查询结果是元组的集合所以多个SELECT语句的结果可进行集合操作。集合操作包括UNION、INTERSECT、EXCEPT。
> 集合查询是对查询结果的集合进行操作,而多重查询条件是多个并列的限制条件。
```
# 查询结果集合的并集
SELECT * FROM Student
WHERE Sdpt='CS'
UNION
SELECT * FROM Student
WHERE Sage<=19
# 查询结果集合的交集
SELECT * FROM Student
WHERE Sdept='CS'
INTERSECT
SELECT * FROM Student
WHERE Sage<=19
# 查询结果的差集
SELECT * FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT * FROM Student
WHERE Sage<=19
```
##### 基于派生表的查询
> 子查询不仅可以出现在WHERE子句中还可以出现在FROM子句中这是子查询生成的临时派生表成为主查询的对象。
```
# 相关子查询改为基于派生表的查询
SELECT Sno,Cno
FROM SC,(SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno) AS AVG_sc(avg_sno,avg_grade)
WHERE SC.sno=avg_sc.avg_sno and SC.Grade >= AVG_sc.avg_grade
```
> 必须为派生关系指定一个别名。
其实在普通的嵌套子查询当中或者链接查询当中,就是两个或者多个表之间的操作,对一个表的查询结果,作为一张中间表进行使用。
## 3 空值处理
> 空值是不确定的、不知道的、不存在的或无意义的值
### 3.1 空值的产生
### 3.2 空值的判断
```
IS NULL //空值
IS NOT NULL// 非空值
```
### 3.3 空值的约束条件
> 如果在字段定义中使用了NOT NULL、Primary Key、UNIQUE则该属性不能使用空值。
### 3.4 空值的算术晕眩、比较运算和逻辑运算
> 空值与另一个值的算术运算结果为空值。
> 空值与另外一个值的比较运算结果为UNKNOWN
> 空值与另外一个值的逻辑运算遵循逻辑运算的法则。如果需要考虑空值则为UNKNOWN如果不虚要考虑空值就能得到结果则为已经得到的结果。

View File

@@ -0,0 +1,148 @@
> 引言:
> 广义上,人们习惯将完整性分为三类:实体完整性、参照完整性、用户自定义完整性。(课本上如此定义)
> 狭义上,有五个最重要的完整性约束方法:主键约束、外键约束、唯一约束、非空约束、检查约束。
> 其中 实体完整性通过主键实现,参照完整性通过外键实现,用户自定义的完整性约束主要包括唯一约束、非空约束、检查约束。
## 主键约束
主键约束是数据表一个或多个用以实现记录唯一性的字段,虽然使用中通常由一个字段标识,但是也可以使用多个字段组成(联合主键)。
主键的作用在于表中的每条记录都具有一个唯一的值,如一个人的身份证号,具有唯一性。用于作为某人的识别标志。创建主键的三种方式:
```
create table TEST_TBL (
-- 主键(主键约束) primary key 唯一的约束该字段里面的数据,不能重复,不可为空
id int primary key
);
```
```
create table TEST_TBL (
-- 主键(主键约束) primary key 唯一的约束该字段里面的数据,不能重复,不可为空
-- 可用于创建联合主键 primary key(参数列表,参数用","隔开)
id int not null,
primary key (id)
);
```
```
-- 追加主键
-- alter table 表名 add primary key字段列表可用于创建联合主键
alter table TEST_TBL add primary key (id);
```
## 外键约束
外键是字表中的一个字段引用父表的主键是确保表与表之间引用完整性的主要机制。用于一张表与另一张表的关联。是能确定另一张表记录的字段用于保持数据的一致性。比如A表中的一个字段是B表的主键那他就可以是A表的外键。
```
create table t1(
id INT PRIMARY KEY,
uid int
-- foreign key外面的键键不在自己表中。如果一张表中有一个字段指向另外一张表的主键那么该字段称之为外键
-- foreign key外键字段 references 外部表(主键字段)
foreign key (uid) references user(id)
);
```
```
-- 追加外键
-- alter table 表名 add [constraint 外键名字] foreign key (外键字段) references 父表(主键字段);
ALTER TABLE t1 ADD CONSTRAINT k_1 FOREIGN KEY (uid)REFERENCES test(id);
ALTER TABLE t1 ADD FOREIGN KEY (uid)REFERENCES test(id);
```
当用户的操作违反了上述规则SQL提供了两种可选方案供数据库实现者使用RESTRICT限制策略CASCADE(级联策略)
* 限制策略
限制策略是SQL的默认策略任何违反参照完整性的更新均被系统拒绝。
* 级联策略
当用户删除或更新外键所指向的键时SQL提供了另一种方案即级联策略。
通过在REFERENCES子句后添加ON DELETE 和 ON UPDATE子句实现
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
如果没有指定ON DELETE 或 ON UPDATE则默认为NO ACTION。
ON DELETE NO ACTION指定如果试图删除某行而该行含有由其它表的现有行中的外键所引用的键则产生错误并回滚 DELETE。
ON UPDATE NO ACTION指定如果试图更新某行中的键值而该行含有由其它表的现有行中的外键所引用的键则产生错误并回滚 UPDATE。
CASCADE允许在表间级联键值的删除或更新操作这些表的外键关系可追溯到执行修改的表。不能为任何具有 timestamp 列的外键和主键指定 CASCADE。
ON DELETE CASCADE
指定如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则也将删除所有包含那些外键的行。如果在目标表上也定义了级联引用操作,则对从那些表中删除的行同样采取指定的级联操作。
ON UPDATE CASCADE
指定如果试图更新某行中的键值,而该行的键值由其它表的现有行中的外键所引用,则所有外键值也将更新成为该键指定的新值。如果在目标表上也定义了级联引用操作,则对在那些表中更新的键值同样采取指定的级联操作。
## 唯一性约束
唯一性约束要求表中某字段在每条记录中为唯一的,与主键类似,当我们对一个一个字段设置了主键约束后依旧可以对另一个字段设置唯一性约束。
```
CREATE TABLE TEST_TBL (
id INT PRIMARY KEY,
NAME VARCHAR(10) NOT NULL UNIQUE
);
```
## 非空约束
NOT NULL他不允许修饰的字段存在NULL值也就是字段内必须有值
```
create table t1(
id INT NOT NULL
);
```
## 检查约束
对属性的CHECK约束、对元组的CHECK约束。
检查约束CHK用于检查输入到特定字段的数据有效性。用于限制列中的值的范围。如果对单个列定义CHECK约束那么该列只允许特定的值。如果对一个表定义CHECK约束,那么此约束会在特定的列中对值进行限制。下面的SQL在”t1”表创建时为”Id”列创建检查约束。约束 “Id” 列必须只包含大于 0 的整数
```
CREATE TABLE t1
(
Id int NOT NULL,
CHECK (Id>0)
)
```
## 其他的完整性约束条件
## 完整性约束命名。
* [CONSTRAINT constraint_name]
```
CREATE TABLE StudentInfo
(
StudentID char(8),
StudentName varchar(10),
StudentSex bit,
CONSTRAINT PK_StudentInfo_ID PRIMARY KEY(StudentID)
);
```
* 完整性约束的增加
```
ALTER TABLE ADD CONSTRAINT 约束名 约束定义
```
* 完整性约束的修改
```
```
* 完整性约束的删除
```
ALTER TABLE DROP CONSTRAINT 约束名
```

View File

@@ -0,0 +1,215 @@
## 1 数据库安全性概述
### 1.1 数据库的不安全因素
1. 非授权用户对数据库恶意存取和破坏
2. 数据库中重要或敏感的数据被泄露
3. 安全环境的脆弱性
### 1.2 安全性标准
> 通用准则 CC Common Criteria
* D 最低级别DOS
* C1 初级的自主安全保护能够实现用户和数据的分离进行自主存取控制DAC保护或限制用户权限的传播。
* C2 安全产品最低档。提供受控的存取控制。Windows2000Oracle7
* B1 标记安全保护对系统的数据加以标记并对标记的主体和客观实体实行强制存取控制。MAC以及审计等安全机制。是真正意义上的安全产品
* B2 结构化保护。建立形势话的安全策略模型并对系统内的所有主体和客体实施DAC和MAC。
* B3 安全域。TCB必须满足访问监控器的要求审计跟踪能力更强并提供系统恢复过程。
* A1 验证设计。提供B3级保护并且给出系统的形式化设计说明和验证。
## 2 数据库安全性控制
> 用户身份鉴别、多层存取控制、审计、视图、数据加密
### 2.1 用户身份鉴别
##### 静态口令鉴别
##### 动态口令鉴别
##### 生物特征鉴别
##### 智能卡鉴别
### 2.2 存取控制
##### 简介
存取控制主要包括定义用户权限和合法权限检查两部分
1. 定义用户权限,并将用户权限登记到数据字典当中。安全规则或授权规则
2. 合法权限检查,当用户发出存取数据库的操作请求后,数据库管理系统查找数据字典,根据安全规则进行合法权限检查。
##### 自主存取控制DAC
> 在自主存取控制方法中,用户对于不同的数据库对象有不同的存取权限,不同的用户对同一存取对象也有不同的权限,而且用户还可以将其拥有的存取权限转手给其他用户。
> 用户权限组成:数据库对象和操作类型。数据库对象包括数据库基本对象和数据库数据对象。定义存取权限称为授权。
1. 权限类型
<table>
<tr>
<th>对象类型</th>
<th>对象</th>
<th>操作类型</th>
</tr>
<tr>
<td rowspan="4">基本对象</td>
<td>模式</td>
<td>CREATE</td>
</tr>
<tr>
<td>基本表</td>
<td>CREATE,ALTER</td>
</tr>
<tr>
<td>视图</td>
<td>CREATE</td>
</tr>
<tr>
<td>索引</td>
<td>CREATE</td>
</tr>
<tr>
<td rowspan="2">数据对象</td>
<td>基本表和视图</td>
<td>SELECT,INSERT,UPDATA,DELETE,REFERENCES,ALL PRIVILEGES</td>
</tr>
<tr>
<td>属性列</td>
<td>SELECT,INSERT,UPDATE,REFERENCES,ALL PRIVILEGES</td>
</tr>
</table>
2. 授权-数据对象权限
```
GRANT <操作权限>,...
ON <对象类型> <对象名>,...
TO <用户>,...
WITH GRANT OPTION
# 示例
GRANT SELECT
ON TABLE Student
TO U1;
GRANT ALL PRIVILEGES
ON TABLE Student
TO U2,U3
WITH GRANT OPTION;
GRANT SELECT
ON TABLE SC
TO PUBLIC;
```
> 将制定对象的制定操作权限授予制定用户。具有授权资格的角色数据库管理员、数据对象的创建者、已经拥有该权限的用户。WITH GRANT OPTION获得这个权限的用户已能够继续授权给其他用户。
3. 收回-数据对象权限
```
REVOKE <权限>,...
ON <对象类型> <对象名>,...
FROM <用户>,...
# 示例
REVOKE UPDATE(Sno)
ON TABLE Student
FROM U4;
REVOKE SELECT
ON TABLE SC
FROM PUBLIC;
```
> 用户可以自主决定将数据存取全向授予何人。所以称为自主存取控制。
3. 创建权限-基本对象权限(模式对象权限)
```
CREATE USER <username>
[WITH][DBA | RESOURCE | CONNECT]
# 实例
```
> * 只有系统的超级用户有权创建一个新的用户。
> * 新创建的数据库用户有三种权限CONNECT/RESOURCE/DBA
> * 没有指定默认是CONNECT权限
> * 每个权限的基本说明:......
4. 数据库角色
> 定义:数据库角色是被命名的一组与数据库操作相关的权限,角色是权限的集合。
```
# 1. 角色创建
CREATE ROLE <角色名>
# 2. 给角色授权
GRANT <权限>,<权限>
ON <对象类型>对象名
TO <角色>,...
# 3. 将一个角色授予其他角色或用户
GRANT <role>,...
TO <role>,<user>,...
[WITH ADMINT OPTION]
# 4. 角色权限回收
REVOKE <privilege>,...
ON <对象类型><对象名>,...
FROM <role>,...
```
##### 强制存取控制MAC
> 在强制存取控制方法中,每一个数据库对象别标以一定的密级,每一个用户也被授予一个几倍的许可证。对于任意对象,只有具有合法许可证的用户才可以存取。相对比较严格。
### 2.3 视图机制
> 为不同的用户定义不同的视图,把数据对象限制在一定的范围内。通过视图机制,把要保密的数据对无权存取的用户隐藏起来,从而自动对数据提供一定程度的安全保护。
```
CREATE VIEW CS_Student
AS SELECT * FROM Student
WHERE Sdept='CS';
GRANT SELECT
ON CS_Student
TO wp
GRANT ALL PRIVILEGES
ON CS_Student
TO zm;
```
### 2.4 审计
> 审计功能把用户对数据库的所有操作自动记录下来放入审计日志。审计员利用甚至日志监控数据库中的各种行为,重现导致数据库现有状况的一系列事件,找出非法存取数据的人、时间和内容。
* 审计事件
* 审计功能
* AUDIT语句和NOAUDIT语句
### 2.5 数据加密
> 根据一定的算法将原始数据——明文,变换为不可直接识别的格式——密文。从而使不知道解密算法的人无法获知数据内容。
* 存储加密
* 传输加密
### 2.6 其他安全性保护
##### 推理控制
##### 隐蔽信道
##### 数据隐私保护

View File

@@ -0,0 +1,77 @@
## 1 断言
## 2 触发器
> trigger触发器是用户定义在关系表示的一类由事件驱动的特殊过程。用户操作自动激活触发器。
### 2.1 定义触发器
```
CREATE TRIGGER <触发器名>
{BEFORE|AFTER} <触发事件> ON <表名>
REFERENCING NEW|OLD ROW AS <变量>
FOR EACH {ROW|STATEMENT}
[WHEN<触发条件>]<触发动作体>
# 行级触发器示例对SC的Grade属性进行修改时若分数增加10%则将此次操作记录到另一个SC_U(Sno,Cno,Oldgrade,Newgrade)中。
CREATE TRIGGER SC_T
AFTER
UPDATE OF Grade ON SC
REFERENCING
OLDROW AS OLDTuple
NEWROW AS NEWTuple
FOR EACH ROW
WHEN(NewTuple.Grade >= 1.1*OldTuple.Grade)
INSERT INT SC_U(Sno,Cno,OldGrade,NewGrade)
VALUES(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)
# 语句级触发器示例每次对标Student的插入操作增加的学生个数记录到新表中
CREATE TRIGGER Student_Count
AFTER
INSERT ON Student
REFERENCING
NEW TABLE AS DELTA
FOR EACH STATEMENT
INSERT INTO StudentInsertLog(Numbers)
SELECT COUNT(*)FROM DELTA
# 定义一个BEFOER行级触发器教授工资不得低于4000如果低于4000自动改为4000
CREATE TRIGGER Insert_Or_Update_Sal
BEFORE
INSERT OR UPDATE ON Teacher
REFERENCING NEW row AS newTuple
FOR EACH ROW
BEGIN
IF(newtuple.Job='教授') AND (newtuple.Sal<4000)
THEN newtuple.Sal:=4000
END IF;
END;
```
> 事件-条件-动作
* 只有表的拥有者创建者才能在表上创建触发器。
* 触发器名,统一模式下唯一
* 表名,只能定义在基本表上。
* 触发事件INSERT、DELETE、UPDATE或其组合时间。ALTER|BEFORE触发时机。
* 触发器类型FOR EACH ROW行级触发器在每一行变化后触发可以引用行级变量OLDROW和NEWROWFOR EACH STATEMENT语句级触发器在整个语句执行完后触发可以引用表级变量OLD TALBE和NEW TABLE。
* 触发条件,触发条件为真时,动作执行
* 触发体动作,过程块。
### 2.2 激活触发器
> 触发器执行由触发事件激活,并由数据库服务器自动执行。
##### 触发顺序
* 执行该表上的BEFOR触发器
* 激活触发器的SQL语句
* 执行该表上的AFTER触发器。
> 如果同一个表上存在多个BEFORE、AFTER触发器遵循先创建限制性的原则按照触发器的创建的时间先后顺序执行。
### 2.3 删除触发器
```
DROP TRIGGER <触发器名> ON <表名>;
```

View File

@@ -0,0 +1,61 @@
## 1 查询处理
### 1.1 查询处理的步骤
> 与编译器进行编译的步骤有点像先对内容进行解析优化然后执行。实际上执行查询的步骤就是对SQL语句进行编译并且执行的步骤。
##### 查询分析
> 对语句进行扫描、词法分析和语法分析。从查询语句中识别出语言符号。处理语法错误。
```
graph TB
词法分析--> 语法分析
```
##### 查询检查
> 对合法的查询语句进行语义检查。名称是否存在、视图操作转化为基本表操作、用户权限和完整性检查。将数据库对象的外部名称抓华为内部表示,生成等价的关系代数表达式,使用查询树(语法分析树)来扩展关系代数表达式。
```
graph TB
语义分析-->符号名转换
符号名转换-->安全性检查
安全性检查-->完整性初步检查
完整性初步检查-->生成查询树
```
##### 查询优化
> 每个查询都会有许多可供选择的执行策略和操作算法,查询优化就是选择一个搞笑执行的查询处理策略。
> 代数优化指关系代数表达式的优化,按照一定的规则,通过对关系代数表达式进行等价变化,改变代数表达式中操作的次序和组合,使得查询效率更加高效。
> 物理优化指存取路径和底层操作算法的选择。选择可以使基于规则、代价、语义的。
```
graph TB
代数优化-->物理优化
```
##### 查询执行
> 依据优化器得到的执行策略生成查询执行计划。由代码生成器生成执行查询计划,回送查询结果。
### 1.2 查询操作的算法示例
##### 选择操作的实现
##### 连接操作的实现
1. 嵌套循环算法
2. 排序-合并算法
3. 索引连接算法
4. hash join算法
## 查询优化
> 查询优化可以分为代数优化、物理优化。也就是逻辑优化和非代数优化。
代数优化是指关系代数表达式的优化,物理优化则是通过存取路径和底层操作算法的选择进行优化。
# 今天已经很累了,下次学习数据库的时候进行补充。

View File

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Some files were not shown because too many files have changed in this diff Show More