• 三层的两次重构


    三层总结


    1.第一次架构

    1.基本三层
    2.分页
    3.主键外键

    1.基本三层

    0.1 model层 主要模拟数据库中的表,以c#的方式对数据进行处理

    1.针对sql数据库进行连接操作的DAL 并且DAL中没个表都要用DAO做后缀名
    当数据库的表是复数形式时,DAO中的后缀改成单数形式

    2.业务逻辑层 BLL 主要是进行行业务逻辑判断 并不是对数据进行直接处理

    3.UI层 直接面对用户 对用户显示功能的用处

    // 三层之中的引用关系

    1.DAL

    2.三层的处理

    A/ 非查询和查询

    1.非查询

    增删改(增)

    UI 1.引用BLL层
    2.创建一个学生对象 收学生对象的所有信息
    3.创建一个bool的实体,将这个实体传递给bll层中
    4.根据bll层的判断,根据判断得出结果


    BLL 1.引用到dal层
    2.接收到ui层传来的实体并且将值传递给dal层
    3.判断DAL层传来的值进行判断是否大于0


    DAL 1.接收到bll层中的实体
    2.执行sql的命令 并用字符注入的方式
    3.创建一个集合
    4.并且将传过来的实体注入到这个集合中
    5.封装sqlhello类
    6.将所有要实现的方法写在里面
    7.将参数传递给sqlhello类中执行并且返回需要实现的方法类型值
    8.返回一个ExecuteNonQuery并且返回到bll层
    UI

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using BLL;
    using Model;

    namespace UI
    {
    public partial class xz : Form
    {


    public xz()
    {
    InitializeComponent();


    }

    private void button1_Click(object sender, EventArgs e)
    {

    studentseres dao = new studentseres();
    students s = new students();
    s.son = textBox1.Text;
    s.name = textBox2.Text;
    s.sex = textBox3.Text;
    s.age = Convert.ToInt32(textBox4.Text);
    bool fiel = dao.zzj(s);
    if (fiel)
    {

    MessageBox.Show("成功");


    }
    else
    {

    MessageBox.Show("失败");

    }

    }
    }
    }

    //增加学生
    public bool zzj(students s)
    {


    return dao.zj(s) > 0;


    }

    //增
    public int zj(students s)
    {


    string sql = "insert into students values(@sno,@name,@sex,@age)";
    List<SqlParameter> pra = new List<SqlParameter>();
    pra.Add(new SqlParameter("@sno", s.son));
    pra.Add(new SqlParameter("@name", s.son));
    pra.Add(new SqlParameter("@sex", s.son));
    pra.Add(new SqlParameter("@age", s.son));
    return sqlhello.ExecuteNonQuery(sql, pra);


    }

    //sqlhello方法


    public class sqlhello
    {


    public static DataTable baba(string sql,List<SqlParameter>pra)
    {


    SqlConnection conn = new SqlConnection("server=.;database=SchoolIDB;uid=sa;pwd=123");
    conn.Open();
    SqlCommand cmd = new SqlCommand(sql, conn);
    if (pra != null)
    {

    cmd.Parameters.AddRange(pra.ToArray()); //查

    }
    DataSet set = new DataSet();
    SqlDataAdapter hh = new SqlDataAdapter(cmd);
    hh.Fill(set);
    return set.Tables[0];

    }
    public static int ExecuteNonQuery(string sql, List<SqlParameter> pra)
    {
    SqlConnection conn = new SqlConnection("server=.;database=SchoolIDB;uid=sa;pwd=123");
    conn.Open();
    SqlCommand cmd = new SqlCommand(sql, conn);
    if (pra != null)
    {

    cmd.Parameters.AddRange(pra.ToArray()); //非查

    }
    return cmd.ExecuteNonQuery();





    }

    }

    }


    2.非查询

    1.删、改

    UI 1.首先必须强制用户选择一行
    2.收集id信息 将id传递给bll层
    3.和增加相同

    private void button3_Click(object sender, EventArgs e)
    {


    if (benben.SelectedRows.Count == 0)
    {

    MessageBox.Show("请先选择一行");


    }
    else
    {

    int id = Convert.ToInt32(benben.SelectedRows[0].Cells["id"].Value);
    bool r = dao.ssc(id);
    if (r)
    {

    MessageBox.Show("删除成功");

    }
    else
    {

    MessageBox.Show("删除失败");
    }


    }

    BLL

    public bool ssc(int id)
    {

    return dao.sc(id) > 0;



    }

    DAL
    public int sc(int id)
    {

    string sql = "delete from students where id=@id ";
    List<SqlParameter> pra = new List<SqlParameter>();
    pra.Add(new SqlParameter("@id", id));
    return sqlhello.ExecuteNonQuery(sql, pra);


    }


    //查询 查询单个值和一批值都可以用datable

    1.创建一个bll层的对象
    2.创建一个用户对象收集用户登录信息
    3.并且将这个值传递给bll
    3.通过bll返回的值得到结果


    //ui 层
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using model;
    using BLL;

    namespace ui
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    userserver u = new userserver();
    private void button1_Click(object sender, EventArgs e)
    {

    user user = new user();
    user.username = textBox1.Text.Trim();
    user.password = textBox2.Text.Trim();
    if (u.checkuser(user))
    {

    MessageBox.Show("登录成功");

    }
    else
    {

    MessageBox.Show("登录失败");
    }
    }
    }
    }

    //bll层
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using model;
    using DAL;

    namespace BLL
    {
    public class userserver
    {

    userDAO dao = new userDAO();
    public bool checkuser(user user)
    {

    user u = dao.getubysername(user.username);
    if (u == null)
    {

    return false;

    }
    else
    {

    return u.password == user.password;


    }


    }

    }
    }


    dal层

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using model;
    using System.Data;
    using System.Data.SqlClient;

    namespace DAL
    {
    public class userDAO
    {
    public user getubysername(string username)
    {


    string sql = "select * from users where username=@username";
    List<SqlParameter> pra = new List<SqlParameter>();
    pra.Add(new SqlParameter("username", username));
    DataTable dt = SqlHelperDAO.getnemane(sql, pra);
    user user = null;
    if (dt.Rows.Count == 1)
    {

    user = new user();
    DataRow row =dt.Rows[0];

    user.userid = Convert.ToInt32(row[0]);
    user.username = row[1].ToString();
    user.password = row[2].ToString();


    }
    return user;

    }


    }

    }

    2.查询一批值

    1.从bll中传递过来的值通过集合存储起来
    2.并且通过当前集合将这个绑定
    3.bll层将数据传递给ui层
    4.dal层查询所有学生信息并且返回一批学生信息
    private studentsserver ss=new studentsserver
    list<student>students=ss.dao()l
    dgvstudents.datasource=students


    2.BLL
    private studensdao dao=new studensdao();
    public List<students> gg()
    {

    return dao.name();


    }

    3.DAL


    //查询所有学生对象
    public List<students> name()
    {


    string sql = "select * from students";
    DataTable u = sqlhello.baba(sql, null);
    List<students> students = new List<students>();
    for (int i = 0; i < u.Rows.Count; i++)
    {

    students ss = new students();
    ss.id = Convert.ToInt32(u.Rows[0]["id"]);
    ss.son = u.Rows[1]["son"].ToString();
    ss.name = u.Rows[2]["name"].ToString();

    students.Add(ss);


    } return students;

    2.分页查询

    ui 1.初始显示所设置
    a.页码 2.一页显示中的数目 3.所有的数目
    private int pageIndex = 1;
    private int pageSize = 10;
    private int count;
    2.将三个参数传递给bll层
    List<Student> students =ss.GetStudentListByPage(pageIndex, pageSize,ref count);
    dgvStudents.DataSource = new BindingList<Student>(students);
    3.通过事件(按钮)来进行分页
    this.pageIndex++;
    if (pageIndex == (count % pageSize == 0 ? count / pageSize : count / pageSize + 1))
    {
    btnNext.Enabled = false;
    }
    btnPrev.Enabled = true;
    this.ShowStudent();
    }

    //if(pageIndex==1)
    {

    btnNext.Enabled = false;
    }
    this.showstudent()

    bll层 1.接收到ui层的参数,并且将参数传递给DAL层
    //public List<Student> GetStudentListByPage(int pageIndex, int pageSize,ref int count)//传递参数
    //{
    // return dao.GetStudentListByPage(pageIndex, pageSize,ref count);//传递给dal层
    //}

    DAL层 从bll层接收到三个参数
    sql:建立一个以id从大到小的表并且以这个为条件
    页码条件:页码*页数-(页数-1)
    页数条件:页码*页数
    建立参数集合与sql命令传递给sqlhello中执行
    将sqlhello传递过来的表接住
    建立一个集合循环讲话值加到里面去
    2.再查询一个coun的命令并且放在sqlhello执行
    并且加入到每个学生的中
    // string sql = "select * from (select ROW_NUMBER() over(order by Id) as sid,* from Students ) temp where sid>=@pageIndex*@pageSize-(@pageSize-1) and sid<=@pageIndex*@pageSize";
    // List<SqlParameter> paras = new List<SqlParameter>();
    // paras.Add(new SqlParameter("@pageIndex", pageIndex));
    // paras.Add(new SqlParameter("@pageSize", pageSize));
    // DataTable dt= SqlHelper.ExecuteTable(sql, paras);
    // List<Student> students = new List<Student>();
    // for (int i = 0; i < dt.Rows.Count; i++)
    // {
    // Student s = new Student();
    // s.Id = Convert.ToInt32(dt.Rows[i]["Id"]);
    // s.Name = dt.Rows[i]["Name"].ToString();
    // s.Sno = dt.Rows[i]["Sno"].ToString();
    // s.Sex = dt.Rows[i]["Sex"].ToString();
    // s.Age = Convert.ToInt32(dt.Rows[i]["Age"]);
    // s.GradeId = Convert.ToInt32(dt.Rows[i]["GradeId"]);
    // students.Add(s);
    // }
    // sql = "select COUNT(*) from Students";//所有的总和
    // count=Convert.ToInt32( SqlHelper.ExecuteScalar(sql, null));//查询所有学生数
    // return students;
    //}

    2.分页第二种方法:
    在ui层设置页码、页数之后传递给bll层,bll层接受到页码与页数后执行命令传递会ui
    按钮(事件) 页码+-1并且执行showstudents 达到分页的效果

    3.外键主键

    基本过程

    将年级对象写到学生对象中,创建学生对象并且用学生对象查找学生的年级id,调用返回的学生对象集合,创建年级对象集合并且调用年级集合的方法,并且将
    通过判断查出来年级id得值覆盖到年级id之中,并且在ui层显示所有学生信息与年级信息
    //注意
    主外键的单向性

    1.一个年级队形可以保存多个学生对象
    2.在年级对象类中根据年级编号来查询年级对象
    3.在创建学生编号的时候new一个年级对象并且调用年级对象的id将学生对象id传递
    3.可以写null (参数)


    例:


    namespace Model //model层 写入年级
    {
    public class Student
    {
    public int Id { get; set; }
    public string Sno { get; set; }
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age { get; set; }
    public int GradeId { get; set; }
    //导航属性
    public Grade Grade { get; set; }


    }
    }

    DAL 层

    public List<Student> GetStudentList()
    {
    string sql = "select * from students";
    DataTable dt= SqlHelper.ExecuteTable(sql, null);
    List<Student> students = new List<Student>();
    for (int i = 0; i < dt.Rows.Count; i++) //查找学生的年级
    {
    Student s = new Student();
    s.Id =Convert.ToInt32( dt.Rows[i]["Id"]);
    s.Sno = dt.Rows[i]["Sno"].ToString();
    s.Name = dt.Rows[i]["Name"].ToString();
    s.Sex = dt.Rows[i]["Sex"].ToString();
    s.Age = Convert.ToInt32(dt.Rows[i]["Age"]);
    s.GradeId = Convert.ToInt32(dt.Rows[i]["GradeId"]);

    students.Add(s);
    }
    return students;
    }

    public List<Grade> GetGradeList()
    {
    string sql = "select * from grades";
    DataTable dt= SqlHelper.ExecuteTable(sql, null); //所有年级
    List<Grade> grades = new List<Grade>();
    for (int i = 0; i < dt.Rows.Count; i++)
    {
    Grade g = new Grade();
    g.GradeId = Convert.ToInt32(dt.Rows[i]["GradeId"]);
    g.GradeName = dt.Rows[i]["GradeName"].ToString();
    grades.Add(g);
    }
    return grades;
    }
    }
    }


    BLL层

    public class StudentService
    {
    private IStudentDAO dao = AbstractFactory.CreatDAO<IStudentDAO>() ;
    //获取所有学生信息
    public List<Student> GetStudentList()
    {
    List<Student> students= dao.GetStudentList();
    List<Grade> grades = new GradeDAO().GetGradeList();//创建对象并且调用方法
    for (int i = 0; i < students.Count; i++)
    {
    for (int j = 0; j < grades.Count; j++) //循环判断
    {
    if (students[i].GradeId == grades[j].GradeId)
    {
    students[i].Grade = grades[j];
    break;
    }
    }
    }
    return students;
    }

    UI层


    private StudentService ss = new StudentService();
    private void FrmStudent_Load(object sender, EventArgs e)
    {
    this.btnPrev.Enabled = false;
    this.ShowStudent();
    }



    第二次重构三层


    1.简单工厂模式
    2.抽象工厂模式
    3.反射
    4,委托


    1.简单工厂模式

    简单工厂设计模式

    1.首先创建一个人的旅游的方法
    private Interface1 jiaoton = gongchang.jiaotong(); //人从工厂得到一个对象法
    public void ff()
    {

    Console.WriteLine("我在旅游");
    jiaoton.row();

    }


    2.创建一个跑的接口 (共同的行为)
    public interface Interface1
    {
    void row();

    }

    3.创建一个具体的跑的对象(车)并且继承跑的接口
    public class CHE:Interface1
    {

    public void row()
    {
    Console.WriteLine("在开车");
    }
    }
    }

    4.创建一个接口工厂 将生成的对象传递给具体的需要的人
    public static Interface1 jiaotong()

    {
    string jt = ConfigurationManager.AppSettings["st"];
    Interface1 jiaotong = null;
    switch (jt)


    {
    case "CHE": jiaotong = new CHE(); break;

    } return jiaotong;


    }
    }

    5.app.config 部分 //注意调用addconfi命令时 需要引用configuration
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>//读取


    <add key="st" value="CHE"/>//通过key值来判断工厂生产的交通工具 //可以通过key获取value,一般用这种方法配置全局内使用的字符串。


    </appSettings>
    </configuration>


    6.创建一个对象并且调用了方法
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication3
    {
    class Program
    {
    static void Main(string[] args)
    {
    ren R = new ren();
    R.ff();

    }
    }
    }


    2.抽象工厂模式


    过程:

    比方说对象是人
    人通过总工厂来选择系列工厂
    比方说系列工厂有两个 一个是高级工厂 一个是低级工厂

    一个交通工具和武器的接口来定义规范
    比方说交通工具有车子和飞机
    武器有ak和火箭


    在总工厂选择了具体的工厂后
    例如 选择了高级工厂,那
    么通过定义可以实现飞机和火箭的实现
    与此类推就是抽象工厂模式


    例子讲解

    具体实现:

    //先选择到工厂 并且在工厂中拿到跑和射击的行为
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class Person
    {
    private AbstractFactory factory = AbstractFactory.ChooseFactory();
    public void Travel()
    {
    IRunable vehicle = factory.CreatVehicle();
    IShotable weapon = factory.CreatWeapon();
    Console.WriteLine("人在旅行....");
    vehicle.Run();
    weapon.Shot();
    }
    }
    }


    总工厂选择


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Configuration;
    using System.Reflection;
    namespace ConsoleApplication2
    {
    public abstract class AbstractFactory
    {
    public abstract IRunable CreatVehicle();
    public abstract IShotable CreatWeapon();
    public static AbstractFactory ChooseFactory()
    {
    string factoryName = ConfigurationManager.AppSettings["FactoryName"]; //加载配文件置并且基于反射技术找到
    //基于反射技术根据类名动态创建该类的对象
    return Assembly.GetExecutingAssembly().CreateInstance("ConsoleApplication2." + factoryName) as AbstractFactory; //实现

    }
    }
    }


    app 配置文件

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
    <add key="FactoryName" value="GDSFactory"/> //选择具体工厂
    </appSettings>
    </configuration>


    具体工厂()
    // 低级工厂 选择具体的接口
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Configuration;

    namespace ConsoleApplication2
    {
    public class GDSFactory : AbstractFactory
    {
    public override IRunable CreatVehicle()
    {
    return new Plane();
    }
    public override IShotable CreatWeapon()
    {
    return new Boom();
    }
    }
    }

    高级工厂 选择具体的接口


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class DXXFactory : AbstractFactory
    {
    public override IRunable CreatVehicle()
    {
    return new Car();
    }
    public override IShotable CreatWeapon()
    {
    return new AK47();
    }
    }
    }


    具体的行为


    using System;
    using System.Collections.Generic;
    using System.Linq; //汽车
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public interface IRunable
    {
    void Run();
    }
    }

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    //射击
    namespace ConsoleApplication2
    {
    public interface IShotable
    {
    void Shot();
    }
    }


    //具体实现
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class Boom : IShotable
    { //炸弹

    public void Shot()
    {
    Console.WriteLine("扔着炸弹轰炸.....");
    }
    }
    }

    //具体实现
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2 //飞机 高大上
    {
    public class Plane : IRunable
    {
    public void Run()
    {
    Console.WriteLine("飞机在天上飞.....");
    }
    }
    }

    //具体实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class Car : IRunable //低级
    {
    public void Run()
    {
    Console.WriteLine("轿车在飞快的跑.....");
    }
    }
    }

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
    public class AK47 : IShotable //低级
    {
    public void Shot()
    {
    Console.WriteLine("拿着AK47在射击....");
    }
    }
    }

    2.委托

    1.委托

    简而言之委托就是讲方法当做参数使用,一个保存方法的类型,委托是一个类,它定义了方法的类型
    、使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,
    同时使得程序具有更好的可扩展性。

    基本语法

    public delegate void dele();
    dele dele=方法(); //注意:如果通过一个委托调用两个方法,会发生方法覆盖。
    dele dele=方法(); //注意:如果通过一个委托调用两个方法,会发生方法覆盖。

    如果要调用两个方法:
    dele dele=test2;
    dele+=test; //这个委托上有两个方法 依次执行
    dele();


    1.匿名函数

    //例1
    button1.Click += delegate(System.Object o, System.EventArgs e)
    { System.Windows.Forms.MessageBox.Show("Click!"); };

    例2

    2.匿名函数直接在调用者中调用函数
    list<studen>resylt=循环方法(学生对象集合,委托方法函数(studen s){return s.sex="男"}) 1.前者
    对象 2.后者是根据对象发生事件

    3.lanbaba表达式

    3.lambabab 表达式
    1. s=>return s.age>=20; //类型对象 => 条件


    4.委托中的四种方法


    Where ToList FirstOrDefault OrderByDescending(最后一个)


    List<Student> result = students.where(s => s.Id).ToList().[0];//根据id查到下表 表达式
    List<Student> result = students.tolist(s => s.Id).ToList();//对应集合
    List<Student> result = students.FirstOrDefault (s => s.Id).ToList();//拿到第一个 默认


    4.反射


    反射的定义:

    反射是通过加载程序集来动态创建具体的实例的过程

    从bll层传递给了工厂层一个学生接口
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Model.Models;
    using IDAL;
    using Factory;

    namespace BLL
    {
    public class StudentService
    {
    private IStudentDAO dao = SessionFactory.CreatDAO<IStudentDAO>();
    public List<Student> GetStudentList()
    {
    return dao.GetList(s => true);
    }
    }
    }

    通过这个学生接口加载配置文件
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Model.Models;
    using IDAL;
    using System.Reflection;
    using System.Configuration;

    namespace Factory
    {
    public class SessionFactory
    {
    public static T CreatDAO<T>() where T : class
    {
    string DllName = ConfigurationManager.AppSettings["DllName"];

    配置文件的内容
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
    <add key="DllName" value="DAL"/>//配置文件的内容
    </appSettings>
    <connectionStrings>
    <add name="SchoolDbContext" connectionString="server=.;database=schooldb;uid=sa;pwd=123" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    </configuration>


    并且执行配置文件的内容
    Assembly assembly = Assembly.Load(DllName);
    加载所查找的程序集的所有的类以循环的方式进行,并且在其中找到当前的类
    Type[] types = assembly.GetTypes();
    Type target = null;
    for (int i = 0; i < types.Length; i++)
    {
    if (typeof(T).IsAssignableFrom(types[i]))
    {
    target = types[i];
    break;
    }
    }

    通过穿过来的参数来创建具体的类的实例
    return (T)Activator.CreateInstance(target);

    1.单例模式

    单例模式的特点:
    a:一个单例只有一个实例
    b:单例必须自己创建一个唯一的实例
    c:单例必须给其他对象提供这个实例

    单例的应用
    a:每台计算机都有若干个打印机,但只能有一个pr 避免两个打印作业同时输出打印机
    b:一个具有主动编号的表可以多个用户使用,一个数据库中只有一个地方分配下一个主键编号,否则会出现主键重复

    public class Singleton
    {
    private static Singleton _instance = null;
    private Singleton(){}
    public static Singleton CreateInstance()
    {
    if(_instance == null)
    {
    _instance = new Singleton();
    }
    return _instance;
    }
    }

  • 相关阅读:
    Oracle 对比insert和delete操作产生的undo
    MySQL 详细解读undo log :insert undo,update undo
    什么是关系型数据库?
    Greenplum 常用数据库管理语句,sql工具
    Greenplum常用的gp_toolkit & pg_catalog监控语句
    Greenplum 与 PostgreSQL 修改元数据(catalog)的方法 allow_system_table_mods
    Greenplum 6 新功能 在线扩容工具GPExpand (转载)
    Pivotal Greenplum 6.0 新特性介绍
    数据库 Hash Join的定义,原理,算法,成本,模式和位图
    Mycat 全局系列号(转载)
  • 原文地址:https://www.cnblogs.com/liyiyong/p/5227027.html
Copyright © 2020-2023  润新知