阿C的博客

Category: Programming (page 1 of 3)

本文主题-规避反爬虫 什么是反爬虫?参看 # 反爬虫(Anti-spider) #

今天穿插一个话题,教大家怎么规避反爬虫。一般来说我们会遇到网站反爬虫策略主要有下面几点:

  1. 限制IP访问频率,超过频率就断开连接。
  2. 限制UA访问频率,超过频率就断开连接。[介绍]
  3. 限制Session访问频率,超过频率就断开连接。
  4. 限制Cookies访问频率,超过频率就断开连接。
附加说明:
针对IP: 爬虫解决办法是,降低爬虫的速度在每个请求前面加上 sleep() 或者不停的更换代理IP。
针对UA: 爬虫解决办法是,准备大量UserAgent随机调用。

我们今天就来针对1、2两点来写出反爬虫的下载模块,别害怕真的很简单。

使用模块
  • requests(网络请求模块)
  • re(正则表达式模块)
  • random(随机选择模块)
实现思路
  1. 代理IP发布网站中获取有效IP地址;
  2. 本地IP访问网页;当本地IP失效时,转换使用代理IP访问网页;
  3. 代理IP失败六次后转换下一个代理IP。

下面我们开整ヽ(●-`Д´-)ノ


第一步、先看看Python的默认UA
import requests

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)
print r.text

运行结果:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "23",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.13.0"
  },
  "json": null,
  "origin": "220.200.59.163",
  "url": "http://httpbin.org/post"
}

我们可以看到,程序请求页面的UA是这样的: python-requests/2.13.0,而正常浏览器请求页面的UA应该是这样的:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0

规避反爬虫-正常UA

反爬虫程序若做上述检测,则当场被抓现形,直接枪毙。

所以呢,我们必须要伪造正常浏览器访问的UA,同时为了一次性解决 2.限制UA访问频率 ,我们还需要伪造大量的UA,请求时随机选取一个,混淆视听。

Continue reading

爬虫第一炮-福利网站:妹子图

基础环境

  • python环境:2.7.13
  • python类库:Requests[1]、beautifulsoup[2]、LXML[3]
pip install Requests
pip install beautifulsoup4
pip install LXML

流程示例图

爬虫教程第一炮之流程示意图

  • 爬虫入口:顾名思义我们需要程序从什么地方开始爬取网页
  • 存储数据:如果获取的网页有你需要的内容则取出数据保存
  • 提取页面URL:如果你你获取到的网页没有你需要的数据,但是有前往该数据页面的地址URL,则获取该地址URL,再次循环爬虫入口爬取

准备工作完了 ヽ(●-`Д´-)ノ ,我们马上开搞码代码了。

一个简单爬虫的诞生大慨需要下面几个步骤(图很简陋、将就着看看)。


第一步、获取顶级爬虫入口

好啦!现在来开始看看网站找一个爬虫入口(开始爬取的页面):http://www.mzitu.com/all/

爬虫教程第一炮之入口页面

Continue reading

Argparse教程

本教程简明地介绍了Python标准库推荐使用的命令行参数解析模块 —— Argparse的使用。这里Argparse的编写环境为Python 3,一些细节有别于2.x版本,特别是一些异常消息,在3.x版本中有所改进。

注意: 有其他两个模块,也完成同样的任务。即 getopt (一个等价于C语言的getopt()) 和 弃用的 optparse。另外,Argparse 是基于 optparse,因此在使用方面非常相似。

概念

在本入门教程中,让我们通过使用ls命令来展示Argparse的功能:

$ ls
cpython  devguide  prog.py  pypy  rm-unused-function.patch
$ ls pypy
ctypes_configure  demo  dotviewer  include  lib_pypy  lib-python ...
$ ls -l
total 20
drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
drwxr-xr-x  4 wena wena 4096 Feb  8 12:04 devguide
-rwxr-xr-x  1 wena wena  535 Feb 19 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Feb  7 00:59 pypy
-rw-r--r--  1 wena wena  741 Feb 18 01:01 rm-unused-function.patch
$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...

从以上的四个命令中,我们能够了解以下几个基本概念:

  • 命令一: ls命令在没有任何参数的情况下也是可以运行的,默认显示当前目录的内容。
  • 命令二: 如果我们想要让它显示更多内容,那么我们需要给它多一点参数。比如,我们想显示一个不同的目录,pypy。我们所做的就是明确指定位置参数(Positional Argument)。这样程序就会根据命令行中的参数得知它所在的位置并进行显示。这个概念更像cp这样的命令,它的基本用法是 cp SRC DEST ,SRC表示的是您想要拷贝的文件,DEST表示你想要将文件拷贝到哪里。
  • 命令三: 现在,我们想要改变程序的行为。在我们的示例中,我们想为每个文件显示更多的信息,而不仅仅是文件名。在这种情况下,-l被称为可选参数(Optinal Argument)
  • 命令四: 最后是显示帮助的文档的一个片段。这是非常有用的,当你遇到你从未使用过的命令时,你可以通过它学习怎么使用。
基本认识

让我们先从一个非常简单的例子开始(它什么也不做):

import argparse
parser = argparse.ArgumentParser()
parser.parse_args()

运行结果:

$ python prog.py
$ python prog.py --help
usage: prog.py [-h]

optional arguments:
  -h, --help  show this help message and exit
$ python prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
$ python prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo

结果分析:

  • 命令一: 若不给参数而运行脚本,将不会得到任何结果。
  • 命令二: 显示 Argparse 模块的有用之处。我们几乎没有做什么,但我们已经得到一个不错的帮助信息。我们无需人为设置–help-h参数,就能得到一不错的帮助信息。
  • 命令三 & 命令四: 指定其他参数会导致错误。
位置参数

一个示例:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo

运行结果:

$ python prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
$ python prog.py --help
usage: prog.py [-h] echo

positional arguments:
  echo

optional arguments:
  -h, --help  show this help message and exit
$ python prog.py foo
foo

结果分析:

  • 我们增加了一个 add_argument() 方法,用来指定程序可接受的命令行参数。在这种情况下,我将命名为符合其功能的参数名称 echo
  • 现在要运行程序,就必须指定一个参数。
  • parse_args() 方法实际上从我们的命令行参数中返回一些数据,在上面的例子中是echo。
  • 这个像“魔法”一样的过程,在 Argparse 中是自动完成的。

注意:尽管自动产生的帮助看起来显示不错,目前不是那么有用。例如我们看到 echo 作为一个位置参数,但是我们仍然无法知道它是做什么用的。所以,我们增加了一些东西,使得它变得更加有用:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print args.echo

运行结果:

$ python prog.py -h
usage: prog.py [-h] echo

positional arguments:
  echo        echo the string you use here

optional arguments:
  -h, --help  show this help message and exit

现在,做一些更有用的事情:(计算输入参数 square 的平方)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
print args.square**2

运行结果:

$ python prog.py 4
Traceback (most recent call last):
  File "prog.py", line 5, in <module>
    print args.square**2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

这个程序不能正确运行,因为 Argparse 会将输入参数当作字符串处理,所以我们需要设置它的类型:(type=int)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number", type=int)
args = parser.parse_args()
print args.square**2

运行结果:

$ python prog.py 4
16
$ python prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'

进行得很顺利。这个程序现在甚至可以在非法输入时报错退出。

可选参数

迄今为止,我们一直在玩位置参数。让我们看看如何添加可选参数:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
    print "verbosity turned on"

运行结果:

$ python prog.py --verbosity 1
verbosity turned on
$ python prog.py
$ python prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]

optional arguments:
  -h, --help            show this help message and exit
  --verbosity VERBOSITY
                        increase output verbosity
$ python prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument

结果分析:

  • 命令一: 程序在指定 –verbosity 时显示内容。该参数实际上是可选的,没有指定运行程序也不会出现错误。请注意,默认情况下,如果不使用可选参数,则相关变量( args.verbosity )将被赋值 None ,这时 if 语句将判断为失败。另外,帮助消息也会相应更改。
  • 命令二: 需要使用 –verbosity 参数时,必须指定值,值是什么无所谓。

上述示例接受 –verbosity 参数的任意值,但对于当前程序,实际上只需要两个值: TrueFalse 。 我们相应地修改代码:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity", action="store_true")
args = parser.parse_args()
if args.verbose:
   print "verbosity turned on"

运行结果:

$ python prog.py --verbose
verbosity turned on
$ python prog.py --verbose 1
usage: prog.py [-h][--verbose]
prog.py: error: unrecognized arguments: 1
$ python prog.py --help
usage: prog.py [-h][--verbose]

optional arguments:
  -h, --help  show this help message and exit
  --verbose   increase output verbosity

结果分析:

  • 命令一: args.verbose 参数现在是一个标记,而不需要一个具体的值。我们甚至更改了该参数的名称以匹配该想法。请注意,我们现在指定一个新的关键字 action ,并赋值“store_true”。 这意味着,如果指定了该参数,则将赋值 True ,不指定意味着为 False
  • 命令二: 当你为此参数指定值时,它会报错。
  • 其他: 请注意不同的帮助文本。
短参数

如果您熟悉命令行的使用,您会注意到我尚未提及到参数的简短版本的话题。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true")
args = parser.parse_args()
if args.verbose:
    print "verbosity turned on"

运行结果:

$ python prog.py -v
verbosity turned on
$ python prog.py --help
usage: prog.py [-h] [-v]

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  increase output verbosity

注意:新功能也反映在帮助文本中。

位置参数和可选参数相结合

我们不断增加程序的复杂度:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
parser.add_argument("-v", "--verbose", action="store_true", help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbose:
    print "the square of {} equals {}".format(args.square, answer)
else:
    print answer

运行结果:

$ python prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
$ python prog.py 4
16
$ python prog.py 4 --verbose
the square of 4 equals 16
$ python prog.py --verbose 4
the square of 4 equals 16
  • 命令一: 我们绑定了一个位置参数,因此无参数传入报错。
  • 命令二 & 命令三: 请注意,顺序并不重要。

我们如何给我们这个程序提供多种详细输出(Multiple Verbosity)的格式,请看代码:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer

运行结果:

$ python prog.py 4
16
$ python prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
$ python prog.py 4 -v 1
4^2 == 16
$ python prog.py 4 -v 2
the square of 4 equals 16
$ python prog.py 4 -v 3
16

除了最后一个外,这些都看起来很好,这在我们的程序中暴露了一个错误。 我们通过限制 –verbosity 参数可以接受的值来解决它:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2], help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer

运行结果:

$ python prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square

positional arguments:
  square                display a square of a given number

optional arguments:
  -h, --help            show this help message and exit
  -v {0,1,2}, --verbosity {0,1,2}
                        increase output verbosity

注意:修改代码也会同时反映出错误消息以及帮助文本。

现在,让我们使用一个不同的方法玩 –verbosity ,这是很常见的。它也匹配 CPython 可执行文件处理其自己的verbose参数的方式(检查 python –help 的输出):

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count", help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer

我们引入了另一个动作 “count” 来计算特定可选参数的出现次数:

$ python prog.py 4
16
$ python prog.py 4 -v
4^2 == 16
$ python prog.py 4 -vv
the square of 4 equals 16
$ python prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python prog.py 4 -h
usage: prog.py [-h] [-v] square

positional arguments:
  square           display a square of a given number

optional arguments:
  -h, --help       show this help message and exit
  -v, --verbosity  increase output verbosity
$ python prog.py 4 -vvv
16
  • 命令一 & 命令一 & 命令三: 是的,脚本的以前版本使用的是一个标志(action=”store_true”)。这里解释一下与“计数”的不同。“计数”,就像“store_true”操作一样,如果不指定-v标志,该标志被认为是 None
  • 命令四: 指定参数的长形式,我们也会得到相同的输出。
  • 命令六: 令人遗憾的是,我们的帮助文本对于我们的脚本获得新特性支持的并不十分丰富,但总是可以通过改进脚本的文档(例如通过help关键字)来修复。
  • 命令七: 最后一个输出会在我们的程序中出现一个BUG。

让我们FIX它:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2

# bugfix: replace == with >=
if args.verbosity >= 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer

运行结果:

$ python prog.py 4 -vvv
the square of 4 equals 16
$ python prog.py 4 -vvvv
the square of 4 equals 16
$ python prog.py 4
Traceback (most recent call last):
  File "prog.py", line 11, in <module>
    if args.verbosity >= 2:
TypeError: unorderable types: NoneType() >= int()
  • 命令一 & 命令二: 输出顺利,并修复了我们以前的Bug。也就是说,我们希望任何值 >= 2 尽可能冗长。
  • 命令三: 存在问题。

让我们FIX这个BUG:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", default=0, help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
    print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
    print "{}^2 == {}".format(args.square, answer)
else:
    print answer

我们刚刚推出了另一个关键字-default。我们将其设置为0,以使其与其他int值相当。请记住,默认情况下,如果未指定可选参数,将赋值None,并且不能与int值进行比较(因此报出TypeError异常)。

再次运行:

$ python prog.py 4
16

到目前为止,我们已经学到了很多东西,但我们仍只是触及了 Argparse 的表面。模块功能非常强大,在我们结束本教程之前,我们将进一步探讨一下。

更上一层楼

如果我们想扩展我们的小程序来执行其他权力,而不仅仅是求平方:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
    print "{} to the power {} equals {}".format(args.x, args.y, answer)
elif args.verbosity >= 1:
    print "{}^{} == {}".format(args.x, args.y, answer)
else:
    print answer

运行结果:

$ python prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
$ python prog.py -h
usage: prog.py [-h] [-v] x y

positional arguments:
  x                the base
  y                the exponent

optional arguments:
  -h, --help       show this help message and exit
  -v, --verbosity
$ python prog.py 4 2 -v
4^2 == 16

注意:到目前为止,我们一直在使用详细程度级别(Verbosity Level)来更改显示的文本。以下示例代替使用详细程度级别来显示更多文本:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
    print "Running '{}'".format(__file__)
if args.verbosity >= 1:
    print "{}^{} ==".format(args.x, args.y),
print answer

运行结果:

$ python prog.py 4 2
16
$ python prog.py 4 2 -v
4^2 == 16
$ python prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16
选项冲突

到目前为止,我们已经使用了两个 argparse.ArgumentParser 实例的方法。 我们来介绍第三个, add_mutually_exclusive_group()。它允许我们指定彼此冲突的参数。我们还要改变程序的其余部分,使新功能更有意义:我们将介绍 –quiet 选项,这将与 –verbose 相反:

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y

if args.quiet:
    print answer
elif args.verbose:
    print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
    print "{}^{} == {}".format(args.x, args.y, answer)

我们的程序现在更简单,为了演示,我们已经去掉了一些功能。无论如何,程序运行输出如下:

$ python prog.py 4 2
4^2 == 16
$ python prog.py 4 2 -q
16
$ python prog.py 4 2 -v
4 to the power 2 equals 16
$ python prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose

这种方式应该很容易遵循。最后一个命令,你可以看到程序获得的灵活性,即混合长形式参数与短格式参数结合的情况。

在我们总结之前,您可能想要告诉用户您的程序的主要目的,以防他们不知道:

import argparse

parser = argparse.ArgumentParser(description="calculate X to the power of Y")
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y

if args.quiet:
    print answer
elif args.verbose:
    print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
    print "{}^{} == {}".format(args.x, args.y, answer)

注意:使用说明略有不同。 注意 [-v | -q] ,它告诉我们,我们可以使用 -v-q ,但不能同时使用两者:

$ python prog.py --help
usage: prog.py [-h] [-v | -q] x y

calculate X to the power of Y

positional arguments:
  x              the base
  y              the exponent

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose
  -q, --quiet
结论

Argparse 模块提供了很多比这里介绍的更多的功能。它的功能文档是非常详细和完全的,有充分的例子。通过本教程,您应该很容易地消化它们,而不会感到不知所措。

原(Ying)文地址:Argparse Tutorial

近一年没有碰python了,感觉宝刀已老,遂写了写自动化发布本地博客的脚本。期间感谢 小长伟 指导。

脚本实现功能:

  • 关闭特定服务
  • 启动XAMPP环境
  • 导出本地博客数据库
  • 修改本地数据库内容
  • 发布博客站点资源(FTP)
  • 覆盖远程博客数据库
  • 模拟网页登录执行配置操作

脚本源码下载:传送门

MySQL注入攻击与防御

一、注入常用函数与字符
二、测试注入
三、注释符
四、版本&主机名&用户&库名
五、表和字段
六、字符串连接&条件语句&时间函数
七、文件操作
八、带外通道
九、绕过技巧
十、注释符&引号
十一、实战正则过滤绕过
十二、防御手段(代码以PHP为例)

原文地址:安全客 & 缓存图片

利刃出鞘,一小时任务系统设计加编码。

前天从翁锟兄弟那里回来,知晓了他们设计活动的整个实现过程。遂剑拔弩张、刀光剑影顷刻间完成了任务系统的设计。

之前还为性能考虑做成富客户端以减轻服务器压力,没必要。客户端依旧仅仅作播放器。业务逻辑全权交服务端,单一管理(不会出现产品新增任务类型服务端需推客户端新解析方案的恶心事情等等)

示例运用了工厂、单例、观察者、职责链、解释器、原型设计模式,实体表设计为四张:任务、任务奖励、任务条件(前/后置)、用户任务明细。

先备份一份代码上博客,明天合并进业务系统。

源代码下载:“任务系统”(.NET)

字段设计规范

1、用DECIMAL代替FLOAT和DOUBLE存储精确浮点数。

浮点数的缺点是会引起精度问题,请看下面一个例子:

mysql> CREATE TABLE table1 (f1 float(10,2),f2 decimal(10,2));
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO table1 VALUES (999998.02, 999998.02);
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t3;
+-----------+-----------+
| f1        | f2        |
+-----------+-----------+
| 999998.00 | 999998.02 |
+-----------+-----------+
1 row in set (0.00 sec)

Continue reading

Least Frequently Used(LFU):

最不经常使用。淘汰一定时期内被访问次数最少的数据。
我会计算为每个缓存对象计算他们被使用的频率。我会把最不常用的缓存对象踢走。

Least Recently Used(LRU):

最近最少使用。根据数据的历史访问记录来进行淘汰数据。常用于页面置换算法,是为虚拟页式存储管理服务的。
我把最近最少使用的缓存对象给踢走。
浏览器就是使用了我(LRU)作为缓存算法。新的对象会被放在缓存的顶部,当缓存达到了容量极限,我会把底部的对象踢走,而技巧就是:我会把最新被访问的缓存对象,放到缓存池的顶部。
更优算法: LRU2 和 2Q,他们就是为了完善 LRU 而存在的。

Least Recently Used2(LRU2):

最近最少使用Twice。
我会把被两次访问过的对象放入缓存池,当缓存池满了之后,我会把有两次最少使用的缓存对象踢走。因为需要跟踪对象2次,访问负载就会随着缓存池的增加而增加。如果把我用在大容量的缓存池中,就会有问题。另外,我还需要跟踪那么不在缓存的对象,因为他们还没有被第二次读取。我比LRU好,而且是 adoptive to access 模式 。

Two Queues(2Q):

双队列。
我把被访问的数据放到 LRU 的缓存中,如果这个对象再一次被访问,我就把他转移到第二个、更大的 LRU 缓存。
我踢走缓存对象是为了保持第一个缓存池是第二个缓存池的1/3。当缓存的访问负载是固定的时候,把 LRU 换成 LRU2,就比增加缓存的容量更好。这种机制使得我比 LRU2 更好,我也是 LRU 家族中的一员,而且是 adoptive to access 模式 。

Continue reading

DISCUZ数据库字典:

(字典比较庞大,若有错误的地方欢迎跟帖指正!)

pre_common_admincp_cmenu后台菜单收藏表

字段 类型 默认 注释
id smallint(6)   编号
title varchar(255)   菜单名称
url varchar(255)   菜单地址
sort tinyint(1) 0 菜单类型,备用
displayorder tinyint(3)   显示顺序
clicks smallint(6) 1 点击数,备用
uid mediumint(8)   添加用户
dateline int(10)   添加时间

Continue reading

下述十四个技巧,是许多人在大量的数据库分析与设计实践中,逐步总结出来的。对于这些经验的运用,读者不能生帮硬套,死记硬背,而要消化理解,实事求是,灵活掌握。并逐步做到:在应用中发展,在发展中应用。

1. 原始单据与实体之间的关系
  可以是一对一、一对多、多对多的关系。在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体。在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证对应多个实体,或多张原始单证对应一个实体。这里的实体可以理解为基本表。明确这种对应关系后,对我们设计录入界面大有好处。
  〖例1〗:一份员工履历资料,在人力资源信息系统中,就对应三个基本表:员工基本情况表、社会关系表、工作简历表。这就是“一张原始单证对应多个实体”的典型例子。

2. 主键与外键
  一般而言,一个实体不能既无主键又无外键E–R图 中, 处于叶子部位的实体,可以定义主键,也可以不定义主键(因为它无子孙), 但必须要有外键(因为它有父亲)。
  主键与外键的设计,在全局数据库的设计中,占有重要地位。当全局数据库的设计完成以后,有个美国数据库设计专家说:“键,到处都是键,除了键之外,什么也没有”,这就是他的数据库设计经验之谈,也反映了他对信息系统核心(数据模型)的高度抽象思想。因为:主键是实体的高度抽象,主键与外键的配对,表示实体之间的连接。

Continue reading

Olderposts

Copyright © 2020 阿C的博客

Theme by AC.AsiaUp ↑