精华内容
下载资源
问答
  • 阿里数据仓库模型设计说明.pdf
  • 数据仓库模型设计说明书数据仓库模型设计说明
  • 数据仓库模型设计说明书模板
  • **数据仓库模型设计说明书 建模思路 模型1 模型2 模型3
  • 用于构建用户偏好模型,是推荐系统引擎基础部分
  • cmdb模型设计

    千次阅读 2019-01-24 22:16:25
    一、创建项目 让我们新开一个副本....咳咳,新建一个项目。 首先,通过virtualenv建立虚拟环境cmdb_env,安装Django,然后创建Django项目cmdb,配置好settings中的语言和...二、模型设计 说明:本项目依然采用...

    一、创建项目

    让我们新开一个副本....咳咳,新建一个项目。

    首先,通过virtualenv建立虚拟环境cmdb_env,安装Django,然后创建Django项目cmdb,配置好settings中的语言和时区,最后新建一个app,名字就叫做assets。这些基本过程以后就不再赘述了,不熟悉的请参考教程的前面部分。

    创建成功后,初始状态如下图所示:

    7.jpg-62.4kB

    二、模型设计

    说明:本项目依然采用SQLite数据库,等下一个项目再使用Mysql。

    模型设计是整个项目的重中之重,其它所有的内容其实都是围绕它展开的。

    而我们设计数据模型的原则和参考依据是前一节分析的项目需求和数据分类表。

    1.资产共有数据模型

    打开assets/models.py文件,首先我们要设计一张资产表:

    class Asset(models.Model):
        """    所有资产的共有数据表    """
        asset_type_choice = (
            ('server', '服务器'),
            ('networkdevice', '网络设备'),
            ('storagedevice', '存储设备'),
            ('securitydevice', '安全设备'),
            ('software', '软件资产'),
        )
    
        asset_status = (
            (0, '在线'),
            (1, '下线'),
            (2, '未知'),
            (3, '故障'),
            (4, '备用'),
            )
    
        asset_type = models.CharField(choices=asset_type_choice, max_length=64, default='server', verbose_name="资产类型")
        name = models.CharField(max_length=64, unique=True, verbose_name="资产名称")     # 不可重复
        sn = models.CharField(max_length=128, unique=True, verbose_name="资产序列号")  # 不可重复
        business_unit = models.ForeignKey('BusinessUnit', null=True, blank=True, verbose_name='所属业务线')
        status = models.SmallIntegerField(choices=asset_status, default=0, verbose_name='设备状态')
    
        manufacturer = models.ForeignKey('Manufacturer', null=True, blank=True, verbose_name='制造商')
        manage_ip = models.GenericIPAddressField(null=True, blank=True, verbose_name='管理IP')
        tags = models.ManyToManyField('Tag', blank=True, verbose_name='标签')
        admin = models.ForeignKey(User, null=True, blank=True, verbose_name='资产管理员', related_name='admin')
        idc = models.ForeignKey('IDC', null=True, blank=True, verbose_name='所在机房')
        contract = models.ForeignKey('Contract', null=True, blank=True, verbose_name='合同')
    
        purchase_day = models.DateField(null=True, blank=True, verbose_name="购买日期")
        expire_day = models.DateField(null=True, blank=True, verbose_name="过保日期")
        price = models.FloatField(null=True, blank=True, verbose_name="价格")
    
        approved_by = models.ForeignKey(User, null=True, blank=True, verbose_name='批准人', related_name='approved_by')
    
        memo = models.TextField(null=True, blank=True, verbose_name='备注')
        c_time = models.DateTimeField(auto_now_add=True, verbose_name='批准日期')
        m_time = models.DateTimeField(auto_now=True, verbose_name='更新日期')
    
        def __str__(self):
            return '<%s>  %s' % (self.get_asset_type_display(), self.name)
    
        class Meta:
            verbose_name = '资产总表'
            verbose_name_plural = "资产总表"
            ordering = ['-c_time']
    

    说明:

    • sn这个数据字段是所有资产都必须有,并且唯一不可重复的!通常来自自动收集的数据中;
    • name和sn一样,也是唯一的;
    • asset_type_choice和asset_status分别设计为两个选择类型
    • adamin和approved_by是分别是当前资产的管理员和将该资产上线的审批员;
    • 导入Django内置的User表,作为我们CMDB项目的用户表,用于保存管理员和审判员等人员信息;
    • asset表中的很多字段内容都无法自动获取,需要我们手动输入,比如合同、备注。

    2.服务器模型

    服务器作为资产的一种,而且是最主要的管理对象,包含了一些主要的信息,其模型结构如下:

    class Server(models.Model):
        """服务器设备"""
        sub_asset_type_choice = (
            (0, 'PC服务器'),
            (1, '刀片机'),
            (2, '小型机'),
        )
    
        created_by_choice = (
            ('auto', '自动添加'),
            ('manual', '手工录入'),
        )
    
        asset = models.OneToOneField('Asset')  # 非常关键的一对一关联!
        sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="服务器类型")
        created_by = models.CharField(choices=created_by_choice, max_length=32, default='auto', verbose_name="添加方式")
        hosted_on = models.ForeignKey('self', related_name='hosted_on_server',
                                      blank=True, null=True, verbose_name="宿主机")  # 虚拟机专用字段
        model = models.CharField(max_length=128, null=True, blank=True, verbose_name='服务器型号')
        raid_type = models.CharField(max_length=512, blank=True, null=True, verbose_name='Raid类型')
    
        os_type = models.CharField('操作系统类型', max_length=64, blank=True, null=True)
        os_distribution = models.CharField('发行版本', max_length=64, blank=True, null=True)
        os_release = models.CharField('操作系统版本', max_length=64, blank=True, null=True)
    
        def __str__(self):
            return '%s--%s--%s <sn:%s>' % (self.asset.name, self.get_sub_asset_type_display(), self.model, self.asset.sn)
    
        class Meta:
            verbose_name = '服务器'
            verbose_name_plural = "服务器"
    

    说明:

    • 每台服务器都唯一关联着一个资产对象,因此使用OneToOneField构建了一个一对一字段,这非常重要!
    • 服务器又可分为几种子类型,这里定义了三种;
    • 服务器添加的方式可以分为手动和自动;
    • 有些服务器是虚拟机或者docker生成的,没有物理实体,存在于宿主机中,因此需要增加一个hosted_on字段;
    • 服务器有型号信息,如果硬件信息中不包含,那么指的就是主板型号;
    • Raid类型在采用了Raid的时候才有,否则为空
    • 操作系统相关信息包含类型、发行版本和具体版本。

    3.安全、网络、存储设备和软件资产的模型

    这部分内容不是项目的主要内容,而且数据大多数不能自动收集和报告,很多都需要手工录入。我这里给出了范例,更多的数据字段,可以自行添加。

    class SecurityDevice(models.Model):
        """安全设备"""
        sub_asset_type_choice = (
            (0, '防火墙'),
            (1, '入侵检测设备'),
            (2, '互联网网关'),
            (4, '运维审计系统'),
        )
    
        asset = models.OneToOneField('Asset')
        sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="安全设备类型")
    
        def __str__(self):
            return self.asset.name + "--" + self.get_sub_asset_type_display() + " id:%s" % self.id
    
        class Meta:
            verbose_name = '安全设备'
            verbose_name_plural = "安全设备"
    
    
    class StorageDevice(models.Model):
        """存储设备"""
        sub_asset_type_choice = (
            (0, '磁盘阵列'),
            (1, '网络存储器'),
            (2, '磁带库'),
            (4, '磁带机'),
        )
    
        asset = models.OneToOneField('Asset')
        sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="存储设备类型")
    
        def __str__(self):
            return self.asset.name + "--" + self.get_sub_asset_type_display() + " id:%s" % self.id
    
        class Meta:
            verbose_name = '存储设备'
            verbose_name_plural = "存储设备"
    
    
    class NetworkDevice(models.Model):
        """网络设备"""
        sub_asset_type_choice = (
            (0, '路由器'),
            (1, '交换机'),
            (2, '负载均衡'),
            (4, 'VPN设备'),
        )
    
        asset = models.OneToOneField('Asset')
        sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="网络设备类型")
    
        vlan_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name="VLanIP")
        intranet_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name="内网IP")
    
        model = models.CharField(max_length=128, null=True, blank=True, verbose_name="网络设备型号")
        firmware = models.CharField(max_length=128, blank=True, null=True, verbose_name="设备固件版本")
        port_num = models.SmallIntegerField(null=True, blank=True, verbose_name="端口个数")
        device_detail = models.TextField(null=True, blank=True, verbose_name="详细配置")
    
        def __str__(self):
            return '%s--%s--%s <sn:%s>' % (self.asset.name, self.get_sub_asset_type_display(), self.model, self.asset.sn)
    
        class Meta:
            verbose_name = '网络设备'
            verbose_name_plural = "网络设备"
    
    
    class Software(models.Model):
        """
        只保存付费购买的软件
        """
        sub_asset_type_choice = (
            (0, '操作系统'),
            (1, '办公\开发软件'),
            (2, '业务软件'),
        )
    
        sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="软件类型")
        license_num = models.IntegerField(default=1, verbose_name="授权数量")
        version = models.CharField(max_length=64, unique=True, help_text='例如: CentOS release 6.7 (Final)',
                                   verbose_name='软件/系统版本')
    
        def __str__(self):
            return '%s--%s' % (self.get_sub_asset_type_display(), self.version)
    
        class Meta:
            verbose_name = '软件/系统'
            verbose_name_plural = "软件/系统"
    

    说明:

    • 每台安全、网络、存储设备都通过一对一的方式唯一关联这一个资产对象。
    • 通过sub_asset_type又细分设备的子类型
    • 对于软件,它没有物理形体,因此无须关联一个资产对象;
    • 软件只管理那些大型的收费软件,关注点是授权数量和软件版本。对于那些开源的或者免费的软件,显然不算公司的资产。

    4.机房、制造商、业务线、合同、资产标签等数据模型

    这一部分是CMDB中相关的内容,数据表建立后,可以通过手动添加。

    class IDC(models.Model):
        """机房"""
        name = models.CharField(max_length=64, unique=True, verbose_name="机房名称")
        memo = models.CharField(max_length=128, blank=True, null=True, verbose_name='备注')
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '机房'
            verbose_name_plural = "机房"
    
    
    class Manufacturer(models.Model):
        """厂商"""
    
        name = models.CharField('厂商名称', max_length=64, unique=True)
        telephone = models.CharField('支持电话', max_length=30, blank=True, null=True)
        memo = models.CharField('备注', max_length=128, blank=True, null=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '厂商'
            verbose_name_plural = "厂商"
    
    
    class BusinessUnit(models.Model):
        """业务线"""
    
        parent_unit = models.ForeignKey('self', blank=True, null=True, related_name='parent_level')
        name = models.CharField('业务线', max_length=64, unique=True)
        memo = models.CharField('备注', max_length=64, blank=True, null=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '业务线'
            verbose_name_plural = "业务线"
    
    
    class Contract(models.Model):
        """合同"""
    
        sn = models.CharField('合同号', max_length=128, unique=True)
        name = models.CharField('合同名称', max_length=64)
        memo = models.TextField('备注', blank=True, null=True)
        price = models.IntegerField('合同金额')
        detail = models.TextField('合同详细', blank=True, null=True)
        start_day = models.DateField('开始日期', blank=True, null=True)
        end_day = models.DateField('失效日期', blank=True, null=True)
        license_num = models.IntegerField('license数量', blank=True, null=True)
        c_day = models.DateField('创建日期', auto_now_add=True)
        m_day = models.DateField('修改日期', auto_now=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '合同'
            verbose_name_plural = "合同"
    
    
    class Tag(models.Model):
        """标签"""
        name = models.CharField('标签名', max_length=32, unique=True)
        c_day = models.DateField('创建日期', auto_now_add=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '标签'
            verbose_name_plural = "标签"
    

    说明:

    • 机房可以有很多其它字段,比如城市、楼号、楼层和未知等等,如有需要可自行添加;
    • 业务线可以有子业务线,因此使用一个外键关联自身模型;
    • 合同模型主要存储财务部门关心的数据;
    • 资产标签模型与资产是多对多的关系。

    5.CPU模型

    通常一台服务器中只能有一种CPU型号,所以这里使用OneToOneField唯一关联一个资产对象,而不是外键关系。服务器上可以有多个物理CPU,它们的型号都是一样的。每个物理CPU又可能包含多核。

    class CPU(models.Model):
        """CPU组件"""
    
        asset = models.OneToOneField('Asset')  # 设备上的cpu肯定都是一样的,所以不需要建立多个cpu数据,一条就可以,因此使用一对一。
        cpu_model = models.CharField('CPU型号', max_length=128, blank=True, null=True)
        cpu_count = models.PositiveSmallIntegerField('物理CPU个数', default=1)
        cpu_core_count = models.PositiveSmallIntegerField('CPU核数', default=1)
    
        def __str__(self):
            return self.asset.name + ":   " + self.cpu_model
    
        class Meta:
            verbose_name = 'CPU'
            verbose_name_plural = "CPU"
    

    6.RAM模型

    某个资产中可能有多条内存,所以这里必须是外键关系。其次,内存的sn号可能无法获得,就必须通过内存所在的插槽未知来唯一确定每条内存。因此,unique_together = ('asset', 'slot')这条设置非常关键,相当于内存的主键了,每条内存数据必须包含slot字段,否则就不合法。

    class RAM(models.Model):
        """内存组件"""
    
        asset = models.ForeignKey('Asset')  # 只能通过外键关联Asset。否则不能同时关联服务器、网络设备等等。
        sn = models.CharField('SN号', max_length=128, blank=True, null=True)
        model = models.CharField('内存型号', max_length=128, blank=True, null=True)
        manufacturer = models.CharField('内存制造商', max_length=128, blank=True, null=True)
        slot = models.CharField('插槽', max_length=64)
        capacity = models.IntegerField('内存大小(GB)', blank=True, null=True)
    
        def __str__(self):
            return '%s: %s: %s: %s' % (self.asset.name, self.model, self.slot, self.capacity)
    
        class Meta:
            verbose_name = '内存'
            verbose_name_plural = "内存"
            unique_together = ('asset', 'slot')  # 同一资产下的内存,根据插槽的不同,必须唯一
    

    7. 硬盘模型

    与内存相同的是,硬盘也可能有很多块,所以也是外键关系。不同的是,硬盘通常都能获取到sn号,使用sn作为唯一值比较合适,也就是unique_together = ('asset', 'sn')。硬盘有不同的接口,这里设置了4种以及unknown,可自行添加其它类别。

    class Disk(models.Model):
        """存储设备"""
    
        disk_interface_type_choice = (
            ('SATA', 'SATA'),
            ('SAS', 'SAS'),
            ('SCSI', 'SCSI'),
            ('SSD', 'SSD'),
            ('unknown', 'unknown'),
        )
    
        asset = models.ForeignKey('Asset')
        sn = models.CharField('硬盘SN号', max_length=128)
        slot = models.CharField('所在插槽位', max_length=64, blank=True, null=True)
        model = models.CharField('磁盘型号', max_length=128, blank=True, null=True)
        manufacturer = models.CharField('磁盘制造商', max_length=128, blank=True, null=True)
        capacity = models.FloatField('磁盘容量(GB)', blank=True, null=True)
        interface_type = models.CharField('接口类型', max_length=16, choices=disk_interface_type_choice, default='unknown')
    
        def __str__(self):
            return '%s:  %s:  %s:  %sGB' % (self.asset.name, self.model, self.slot, self.capacity)
    
        class Meta:
            verbose_name = '硬盘'
            verbose_name_plural = "硬盘"
            unique_together = ('asset', 'sn')
    

    8.网卡模型

    一台设备中可能有很多块网卡,所以网卡与资产也是外键的关系。另外,由于虚拟机的存在,网卡的mac地址可能会发生重复,无法唯一确定某块网卡,因此通过网卡型号加mac地址的方式来唯一确定网卡。

    class NIC(models.Model):
        """网卡组件"""
    
        asset = models.ForeignKey('Asset')  # 注意要用外键
        name = models.CharField('网卡名称', max_length=64, blank=True, null=True)
        model = models.CharField('网卡型号', max_length=128)
        mac = models.CharField('MAC地址', max_length=64)  # 虚拟机有可能会出现同样的mac地址
        ip_address = models.GenericIPAddressField('IP地址', blank=True, null=True)
        net_mask = models.CharField('掩码', max_length=64, blank=True, null=True)
        bonding = models.CharField('绑定地址', max_length=64, blank=True, null=True)
    
        def __str__(self):
            return '%s:  %s:  %s' % (self.asset.name, self.model, self.mac)
    
        class Meta:
            verbose_name = '网卡'
            verbose_name_plural = "网卡"
            unique_together = ('asset', 'model', 'mac')  # 资产、型号和mac必须联合唯一。防止虚拟机中的特殊情况发生错误。
    

    9.日志模型

    CMDB必须记录各种日志,这是毫无疑问的!我们通常要记录事件名称、类型、关联的资产、子事件、事件详情、谁导致的、发生时间。这些都很重要!

    尤其要注意的是,事件日志不能随着关联资产的删除被一并删除,也就是我们设置on_delete=models.SET_NULL的意义!

    class EventLog(models.Model):
        """
        日志.
        在关联对象被删除的时候,不能一并删除,需保留日志。
        因此,on_delete=models.SET_NULL
        """
    
        name = models.CharField('事件名称', max_length=128)
        event_type_choice = (
            (0, '其它'),
            (1, '硬件变更'),
            (2, '新增配件'),
            (3, '设备下线'),
            (4, '设备上线'),
            (5, '定期维护'),
            (6, '业务上线\更新\变更'),
        )
        asset = models.ForeignKey('Asset', blank=True, null=True, on_delete=models.SET_NULL)  # 当资产审批成功时有这项数据
        new_asset = models.ForeignKey('NewAssetApprovalZone', blank=True, null=True, on_delete=models.SET_NULL)  # 当资产审批失败时有这项数据
        event_type = models.SmallIntegerField('事件类型', choices=event_type_choice, default=4)
        component = models.CharField('事件子项', max_length=256, blank=True, null=True)
        detail = models.TextField('事件详情')
        date = models.DateTimeField('事件时间', auto_now_add=True)
        user = models.ForeignKey(User, blank=True, null=True, verbose_name='事件执行人', on_delete=models.SET_NULL)  # 自动更新资产数据时没有执行人
        memo = models.TextField('备注', blank=True, null=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name = '事件纪录'
            verbose_name_plural = "事件纪录"
    

    10.新资产待审批区模型

    新资产的到来,并不能直接加入CMDB数据库中,而是要通过管理员审批后,才可以上线的。这就需要一个新资产的待审批区。在该区中,以资产的sn号作为唯一值,确定不同的资产。除了关键的包含资产所有信息的data字段,为了方便审批员查看信息,我们还设计了一些厂商、型号、内存大小、CPU类型等字段。同时,有可能出现资产还未审批,更新数据就已经发过来的情况,所以需要一个数据更新日期字段。

    class NewAssetApprovalZone(models.Model):
        """新资产待审批区"""
    
        sn = models.CharField('资产SN号', max_length=128, unique=True)  # 此字段必填
        asset_type_choice = (
            ('server', '服务器'),
            ('networkdevice', '网络设备'),
            ('storagedevice', '存储设备'),
            ('securitydevice', '安全设备'),
            ('IDC', '机房'),
            ('software', '软件资产'),
        )
        asset_type = models.CharField(choices=asset_type_choice, default='server', max_length=64, blank=True, null=True,
                                      verbose_name='资产类型')
    
        manufacturer = models.CharField(max_length=64, blank=True, null=True, verbose_name='生产厂商')
        model = models.CharField(max_length=128, blank=True, null=True, verbose_name='型号')
        ram_size = models.PositiveIntegerField(blank=True, null=True, verbose_name='内存大小')
        cpu_model = models.CharField(max_length=128, blank=True, null=True, verbose_name='CPU型号')
        cpu_count = models.PositiveSmallIntegerField(blank=True, null=True)
        cpu_core_count = models.PositiveSmallIntegerField(blank=True, null=True)
        os_distribution = models.CharField(max_length=64, blank=True, null=True)
        os_type = models.CharField(max_length=64, blank=True, null=True)
        os_release = models.CharField(max_length=64, blank=True, null=True)
    
        data = models.TextField('资产数据')  # 此字段必填
    
        c_time = models.DateTimeField('汇报日期', auto_now_add=True)
        m_time = models.DateTimeField('数据更新日期', auto_now=True)
        approved = models.BooleanField('是否批准', default=False)
    
        def __str__(self):
            return self.sn
    
        class Meta:
            verbose_name = '新上线待批准资产'
            verbose_name_plural = "新上线待批准资产"
            ordering = ['-c_time']
    

    11.总结

    通过前面的内容,我们可以看出CMDB数据模型的设计非常复杂,我们这里还是省略了很多不太重要的部分,就这样总共都有400多行代码。其中每个模型需要保存什么字段、采用什么类型、什么关联关系、定义哪些参数、数据是否可以为空,这些都是踩过各种坑后总结出来的,不是随便就能定义的。所以,请务必详细阅读和揣摩这些模型的内容。

    一切没有问题之后,注册app,然后makemigrations以及migrate!

    出处:http://www.liujiangblog.com/course/django/118

    展开全文
  • 原创曲轴磨床家具设计(全套CAD图纸,三维模型设计说明书)
  • 2、存储系统:使用模型机的存储模块,说明存储器的输入输出时序,模块连接方式等。 3、运算器:使用模型机的器件,组成带有片间串行进位16位算数逻辑运算功能的运算器。 4、微程序控制器模块:使用教学机的系统,...
  • 这是基于J2EE的B2C电子商城系统的域模型设计说明
  • Neo4j数据模型设计

    2017-06-19 09:23:56
    引言:数据模型设计是数据建模的第一步,因为Neo4j不需要模式结构定义,所以使用简单框图就可以为一个项目或应用设计数据模型。创建数据模型之后,就可以使用SDN进行数据实体建模和一些数据访问的设计。 本文选自...

    引言:数据模型设计是数据建模的第一步,因为Neo4j不需要模式结构定义,所以使用简单框图就可以为一个项目或应用设计数据模型。创建数据模型之后,就可以使用SDN进行数据实体建模和一些数据访问的设计。
    本文选自《Neo4j全栈开发》。

      开始数据模型设计,一般通过分析业务需求就可以提取出需要建立的节点和关系,然后使用节点和关系画出框图,即可完成数据模型的设计。下面通过两个实例来简要说明数据模型的设计过程。

    用户访问控制数据模型

      在一个访问控制系统中,它的业务需求可以简单地描述为:怎样控制一个用户的访问权限。即一个用户登录系统后,他对系统的哪些资源具有访问权限。通过分析和结合以往的经验,我们可能需要四个节点,分别是用户、部门、角色和资源;三个关系,分别是隶属、拥有和权限。这样,我们就可以画出下图的用户访问控制数据模型。
                 图片描述
      这个数据模型是否合理、是否符合业务需求?我们可以用这个简单框图模拟一下业务流程,简单地测试一下它的合理性。首先看看从这个框图中能不能读出类似这样的信息:隶属于一个部门的一个用户拥有哪些角色就能对哪些资源具有访问权限。如果可以,就可以说明这个模型设计是可行的。
      很明显,这个数据模型设计的业务流程是通顺的。因为对于这个框图,我们可以这样读出它的流程:部门具有一些隶属用户,用户拥有一些角色,角色对一些资源具有访问权限。
      有了这个数据模型之后,就可以对节点和关系进行建模了。在建模中再来确定节点和关系的属性,例如,用户节点可能需要用户名、密码、性别、邮箱、创建日期等属性,同时还要确定关系的对等方式,例如,是一对一、一对多还是多对多等。对于这个实例来说,用户与部门的隶属关系是多对一关系,用户与角色的拥有关系和角色与资源的权限关系都是多对多关系。

    购物网站数据模型

      如果觉得上面的数据模型简单了一点,那么接下来我们使用一个业务需求比较复杂的实例来试一试,比如一个购物网站。购物网站的业务需求大概具有这样的流程:首先商家上架了商品,然后顾客浏览或查找商品,顾客找到自己需要的商品之后,确定购买,接着使用他的账户支付款项,商家收到货款后,将商品快递给顾客,从而完成一笔交易。根据这个业务流程,我们画出下图的数据模型。
                图片描述
      使用这个数据模型,我们同样也可以先测试一下,即看一看它能不能通顺地读出一个购物网站的基本流程。比如完成一个完整的购物流程,首先是商家的库存要上架商品,然后是顾客购买商品,即商品出售形成订单;接下来是顾客结算订单,使用账户付款,形成支付记录,同时商家账户收到款项,并且订单进入发货状态,同时生成物流记录;这时候,商家的库存办理商品出库,这样商品就通过快递进入送货过程之中;最后顾客从收货地址收到商品,并对订单执行确认收货操作,同时对商品进行评价,至此完成一次购物流程。这就可以说明,这个数据模型所表现的业务流程是通顺的,所以它的设计是合理的。
      一般的购物网站还有购物车这一项,以满足顾客一次选购多个商品的需求,所以还必须设计一个购物车,即在上述流程中插入一个挑选商品到购物车的过程。其中购物车只是顾客与商品的一个关联关系。
               图片描述
      这下应该很完整了吧?这个模型的整个流程可以通过数据库来表示。下图是一个网上书店的模拟数据。
               图片描述
      其中“顾客1”挑选了两本书到他的购物车中,“顾客2”购买了一本小说,完成了一个完整的购物流程。
      不过,如果再仔细想想,则可能会发现,上面的流程还需要更多的细化。比如,上面的数据模型虽然可以表现一个正常交易的流程,但是如果出现不正常的交易情况,那这个数据模型就走不通了。例如,顾客下单后,有可能又不要了,所以,这就需要有撤销订单流程。又如,顾客收到商品之后,可能因为质量问题需要退货和退款,所以,还需要增加相应的退货和退款处理流程。另外,商家售卖的一种商品中还有可能具有型号、颜色、价格和库存数量等不同分类,所以,对于商品节点还有必要进行细分。
      不难看出,对上面的数据模型还必须再进行加工和细化。当然,除了这些,还可能有其他各种各样的情况。不过,不管是什么情况,都可以通过简单框图对数据模型进行细化和加工。至于最终怎么建立起一个完整的购物网站数据模型,这里就不再深入探索了。
      本文选自《Neo4j全栈开发》,点此链接可在博文视点官网查看此书。
                          图片描述

    展开全文
  • 数据模型设计标准

    2018-09-01 10:42:14
    主要针对设计数据库表结构进行的标准说明文档,为设计人员设计数据模型时参考标准
  • 本次课程设计通过设计一个复杂计算机模型的方案,微指令、微程序的设计实现计算机的基本功能、经过不断调试最终达到了设计要求,从而较为系统地掌握计算机中的运算器、寄存器、译码电路、存储器、和存储微指令等硬件...
  • 深度学习模型设计

    2020-08-23 12:55:30
    文章目录深度学习模型设计非线性特征线性投影+非线性激活函数相比于传统分类模型设计越深,越宽多分枝残差慎用激活函数稀疏连接 深度学习模型设计 非线性特征 线性的特征空间是有限的,很难表示非线性的分布,变化越...

    深度学习模型设计

    非线性特征

    在这里插入图片描述
    线性的特征空间是有限的,很难表示非线性的分布,变化越大越明显。而非线性特征学习在于很难学到特征,使其表现更好。

    线性投影+非线性激活函数

    在这里插入图片描述
    尝试把线性特征拉到非线性空间,更深的网络描述更丰富的特征。

    相比于传统分类

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    综上三点说明深度学习较比于传统分类效果较好。

    模型设计

    越深,越宽

    设计怎么样的深度宽度的网络效果更好。

    多分枝

    一般来说,多分枝比单分支要好,但多分枝运行在低功耗的硬件上,运行要慢。
    在这里插入图片描述

    残差

    保证学到的error更好的回传。
    在这里插入图片描述

    慎用激活函数

    更多的非线性让数据分布更加的分散,拉到边缘无法聚集。

    稀疏连接

    达到一定的平衡,稀疏要素不会让模型变差,在速度上有很大的帮助。

    展开全文
  • CMMI 能力成熟度模型集成 认证 资料之详细设计说明书模板
  • DDD(领取驱动设计)系列主题之失血模型,贫血模型与充血模型

    目录

    失血模型,贫血模型,充血模型和胀血模型定义及优点和缺点

    失血模型

    贫血模型

    充血模型

    胀血模型

    失血模型,贫血模型,充血和胀血代码样例

    失血模型代码样例

    贫血模型代码样例

    充血模型代码样例

    DDD分层架构模型及基于贫血模型的微服务代码模型

    DDD 分层架构模型

    基于贫血模型的微服务代码模型

    综合评价


    失血模型,贫血模型,充血模型和胀血模型定义及优点和缺点

    领域模型分为4大类:失血模型、贫血模型、充血模型、胀血模型。这类理论都是由软件设计领域的大牛(如Martin Fowler)提出来的,有其背景和原因。

    想要理解这几个分类,先要知道“血”指的是Domain Object的Domain层内容

    失血模型

    Domain Object(领域对象)模型仅仅包含对象属性的定义和操作对象属性的getter/setter方法所有的业务逻辑完全由Business Logic层(业务逻辑层)中的服务类来完成。这种类在java中叫POJO,在.NET中叫POCO。

    优点

    • 领域对象结构简单

    缺点

    • 肿胀的业务服务代码逻辑,难于理解和维护

    • 无法良好的应对复杂业务逻辑和场景

    贫血模型

    Domain Object(领域对象)模型包含对象属性的定义和操作对象属性的getter/setter方法包含了对象的行为(例如:就像一个完整的人,具有一些属性如姓名、性别、年龄等,还具有一些能力,如走路、吃饭、恋爱等,这样才是一个完整的对象),不包含依赖Dao层(持久层)的业务逻辑。这部分依赖于Dao层的业务逻辑将会放到Business Logic层(业务逻辑层)中的服务类来实现组合逻辑也由服务类负责。可以看出,贫血模型中的领域对象是不依赖于持久层的代码架构层次结构是Client-> Business Facade Service -> Business Logic Service(Business Logic Service是依赖Domain Object的行为) -> Data Access Service

    优点

    • 层次结构清楚,各层之间单向依赖

    • 对于只有少量业务逻辑的应用来说,使用起来非常自然

    • 开发迅速,易于理解

    缺点

    • 无法良好的应对非常复杂逻辑和场景

    充血模型

    Domain Object(领域对象)模型包含对象属性的定义和操作对象属性的getter/setter方法包含了大多数相关的业务逻辑,也包含了依赖于持久层的业务逻辑, Business Logic层是很薄的一层,仅仅简单封装少量业务逻辑以及控制事务、权限逻辑等,不和DAO层打交道。所以,使用充血模型的领域对象是依赖于持久层的。代码架构层次结构是Client-> Business Facade Service -> Business Logic Service -> Domain Object -> Data Access Service

    优点

     

    •  更加符合OO的原则
    • Business Logic层很薄,符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重,只充当Facade的角色,不和DAO打交道。

    缺点

    • 什么样的逻辑应该放在Domain Object中,什么样的业务逻辑应该放在Business Logic中,这是很含糊的。即使划分好了业务逻辑,由于分散在Business Logic和Domain Object层中,不能更好的分模块开发。熟悉业务逻辑的开发人员需要渗透到Domain Logic中去,而在Domian Logic又包含了持久化,对于开发者来说这十分混乱。 
    • 其次,因为Business Logic要控制事务并且为上层提供一个统一的服务调用入口点,它就必须把在Domain Logic里实现的业务逻辑全部重新包装一遍,完全属于重复劳动。

     

    胀血模型

    Domain Object(领域对象)模型包含对象属性的定义和操作对象属性的getter/setter方法包含了所有相关的的业务逻辑,也包含了不想关的其它应用逻辑(如授权、事务等)。胀血模型取消了Business Logic层(业务逻辑层)只剩下Domain Object和DAO两层,在Domain Object的Domain Logic上面封装事务,授权逻辑等

    优点

    •  简化了代码分层结构
    • 也算符合面向对象设计

    缺点

    • 取消了Business Logic层(业务逻辑层),在Domain Object的Domain Logic上面封装事务,授权等很多本不应该属于领域对象的逻辑,使业务逻辑再次进行到混论的状态,引起了Domain Object模型的不稳定
    • 代码理解和维护性差

    失血模型,贫血模型,充血和胀血代码样例

    失血模型代码样例

    下面用举一个具体的代码来说明:

    • 一个实体类叫做Item,指的是一个拍卖项目 
    • 一个DAO接口类叫做ItemDao
    • 一个DAO接口实现类叫做ItemDaoHibernateImpl 
    • 一个业务逻辑类叫做ItemManager(或者叫做ItemService) 

    Java代码:  

    public class Item implements Serializable { 
         private Long id = null; 
         private int version; 
         private String name; 
         private User seller; 
         private String description; 
         private MonetaryAmount initialPrice; 
         private MonetaryAmount reservePrice; 
         private Date startDate; 
         private Date endDate; 
         private Set categorizedItems = new HashSet(); 
         private Collection bids = new ArrayList(); 
         private Bid successfulBid; 
         private ItemState state; 
         private User approvedBy; 
         private Date approvalDatetime; 
         private Date created = new Date(); 
         //getter/setter方法省略不写,避免篇幅太长 
    }

    Java代码:  

    public interface ItemDao { 
         public Item getItemById(Long id); 
         public Collection findAll(); 
         public void updateItem(Item item); 
    }

    ItemDao定义持久化操作的接口,用于隔离持久化代码。

    Java代码:

    public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport { 
         public Item getItemById(Long id) { 
             return (Item) getHibernateTemplate().load(Item.class, id); 
         } 
         public Collection findAll() { 
             return (List) getHibernateTemplate().find("from Item"); 
         } 
         public void updateItem(Item item) { 
             getHibernateTemplate().update(item); 
         } 
    }

    ItemDaoHibernateImpl完成具体的持久化工作,请注意,数据库资源的获取和释放是在ItemDaoHibernateImpl里面处理的,每个DAO方法调用之前打开Session,DAO方法调用之后,关闭Session。(Session放在ThreadLocal中,保证一次调用只打开关闭一次)

    Java代码:

    public class ItemManager { 
         private ItemDao itemDao; 
         public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao;} 
         public Bid loadItemById(Long id) { 
             itemDao.loadItemById(id); 
         } 
         public Collection listAllItems() { 
             return   itemDao.findAll(); 
         } 
         public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount, 
                                 Bid currentMaxBid, Bid currentMinBid) throws BusinessException { 
                 if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) { 
                 throw new BusinessException("Bid too low."); 
         } 
        
         // Auction is active 
         if ( !state.equals(ItemState.ACTIVE) ) 
                 throw new BusinessException("Auction is not active yet."); 
        
         // Auction still valid 
         if ( item.getEndDate().before( new Date() ) ) 
                 throw new BusinessException("Can't place new bid, auction already ended."); 
        
         // Create new Bid 
         Bid newBid = new Bid(bidAmount, item, bidder); 
        
         // Place bid for this Item 
         item.getBids().add(newBid); 
         itemDao.update(item);      //   调用DAO完成持久化操作 
         return newBid; 
         } 
    }

    事务的管理是在ItemManger这一层完成的ItemManager实现具体的业务逻辑。除了常见的和CRUD有关的简单逻辑之外,这里还有一个placeBid的逻辑,即项目的竞标。 

    以上是一个完整的第一种模型的示例代码。在这个示例中,placeBid,loadItemById,findAll等等业务逻辑统统放在ItemManager中实现,而Item只有getter/setter方法。

    贫血模型代码样例

    下面用举一个具体的代码来说明:

    • 一个带有业务逻辑的实体类,即Domain Object是Item。
    • 一个DAO接口ItemDao。
    • 一个DAO实现ItemDaoHibernateImpl。
    • 一个业务逻辑对象ItemManager。

    Java代码:  

    public class Item implements Serializable { 
         //   所有的属性和getter/setter方法同上,省略 
         public Bid placeBid(User bidder, MonetaryAmount bidAmount, 
                             Bid currentMaxBid, Bid currentMinBid) 
                 throws BusinessException { 
        
                 // Check highest bid (can also be a different Strategy (pattern)) 
                 if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) { 
                         throw new BusinessException("Bid too low."); 
                 } 
        
                 // Auction is active 
                 if ( !state.equals(ItemState.ACTIVE) ) 
                         throw new BusinessException("Auction is not active yet."); 
        
                 // Auction still valid 
                 if ( this.getEndDate().before( new Date() ) ) 
                         throw new BusinessException("Can't place new bid, auction already ended."); 
        
                 // Create new Bid 
                 Bid newBid = new Bid(bidAmount, this, bidder); 
        
                 // Place bid for this Item 
                 this.getBids.add(newBid);   // 请注意这一句,透明的进行了持久化,但是不能在这里调用ItemDao,Item不能对ItemDao产生依赖!return newBid; 
         } 
    }

    竞标这个业务逻辑被放入到Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDO这种O/R Mapping的支持,我们是无法实现这种透明的持久化行为的。但是请注意,Item里面不能去调用ItemDAO,对ItemDAO产生依赖! 

    Java代码:  

    public interface ItemDao { 
         public Item getItemById(Long id); 
         public Collection findAll(); 
         public void updateItem(Item item); 
    }

    ItemDao定义持久化操作的接口,用于隔离持久化代码。

    Java代码:

    public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport { 
         public Item getItemById(Long id) { 
             return (Item) getHibernateTemplate().load(Item.class, id); 
         } 
         public Collection findAll() { 
             return (List) getHibernateTemplate().find("from Item"); 
         } 
         public void updateItem(Item item) { 
             getHibernateTemplate().update(item); 
         } 
    }

    ItemDaoHibernateImpl完成具体的持久化工作

    Java代码:

    public class ItemManager { 
         private ItemDao itemDao; 
         public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao;} 
         public Bid loadItemById(Long id) { 
             itemDao.loadItemById(id); 
         } 
         public Collection listAllItems() { 
             return   itemDao.findAll(); 
         } 
         public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount, 
                                 Bid currentMaxBid, Bid currentMinBid) throws BusinessException { 
             item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid); 
             itemDao.update(item);     // 必须显式的调用DAO,保持持久化 
         } 
    }

     

    充血模型代码样例

    下面用举一个具体的代码来说明:

    •   Item:包含了实体类信息,也包含了所有的业务逻辑 
    •   ItemDao:持久化DAO接口类 
    •   ItemDaoHibernateImpl:DAO接口的实现类 

    Java代码:  

    public interface ItemDao { 
         public Item getItemById(Long id); 
         public Collection findAll(); 
         public void updateItem(Item item); 
    }

    ItemDao定义持久化操作的接口,用于隔离持久化代码。

    Java代码:

    public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport { 
         public Item getItemById(Long id) { 
             return (Item) getHibernateTemplate().load(Item.class, id); 
         } 
         public Collection findAll() { 
             return (List) getHibernateTemplate().find("from Item"); 
         } 
         public void updateItem(Item item) { 
             getHibernateTemplate().update(item); 
         } 
    }

    ItemDaoHibernateImpl完成具体的持久化工作

    Java代码:

    public class Item implements Serializable { 
        //所有的属性和getter/setter方法都省略 
        private static ItemDao itemDao; 
         public void setItemDao(ItemDao itemDao) {this.itemDao = itemDao;} 
        
         public static Item loadItemById(Long id) { 
             return (Item) itemDao.loadItemById(id); 
         } 
         public static Collection findAll() { 
             return (List) itemDao.findAll(); 
         } 
     
         public Bid placeBid(User bidder, MonetaryAmount bidAmount, 
                         Bid currentMaxBid, Bid currentMinBid) 
         throws BusinessException { 
        
             // Check highest bid (can also be a different Strategy (pattern)) 
             if (currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0) { 
                     throw new BusinessException("Bid too low."); 
             } 
            
             // Auction is active 
             if ( !state.equals(ItemState.ACTIVE) ) 
                     throw new BusinessException("Auction is not active yet."); 
            
             // Auction still valid 
             if ( this.getEndDate().before( new Date() ) ) 
                     throw new BusinessException("Can't place new bid, auction already ended."); 
            
             // Create new Bid 
             Bid newBid = new Bid(bidAmount, this, bidder); 
            
             // Place bid for this Item 
             this.addBid(newBid); 
             itemDao.update(this);       //   调用DAO进行显式持久化 
             return newBid; 
         } 
    }

     


    DDD分层架构模型及基于贫血模型的微服务代码模型

    DDD 分层架构模型

    它包括用户接口层、应用层、领域层和基础层,分层架构各层的职责边界非常清晰,又能有条不紊地分层协作。

    • 用户接口层:面向前端提供服务适配,面向资源层提供资源适配。这一层聚集了接口适配相关的功能。
    • 应用层职责:实现服务组合和编排,适应业务流程快速变化的需求。这一层聚集了应用服务和事件相关的功能。
    • 领域层:实现领域的核心业务逻辑。这一层聚集了领域模型的聚合、聚合根、实体、值对象、领域服务和事件等领域对象,以及它们组合所形成的业务能力。
    • 基础层:贯穿所有层,为各层提供基础资源服务。这一层聚集了各种底层资源相关的服务和能力。

    分层架构的一个重要原则是每层只能与位于其下方的层发生耦合。

    分层架构可以简单分为两种,即严格分层架构和松散分层架构。在严格分层架构中,某层只能与位于其直接下方的层发生耦合,而在松散分层架构中,则允许某层与它的任意下方层发生耦合

    分层架构的优点,Martin Fowler在《Patterns of Enterprise Application Architecture》一书中给出了答案:

    1.     开发人员可以只关注整个结构中的某一层
    2.     可以很容易的用新的实现来替换原有层次的实现
    3.     可以降低层与层之间的依赖
    4.     有利于标准化
    5.     有利于各层逻辑的复用

    适当的分层体系结构将开发层面进行隔离,这些层不受其他层的更改的影响,从而使重构更加容易。划分任务并定义单独的层是架构师面临的挑战。当需求很好地适应了模式时,这些层将易于解耦或分层开发。

    使用场景:

    •     需要快速构建的新应用程序
    •     需要严格的可维护性和可测试性标准的应用

    基于贫血模型的微服务代码模型

    现在,我们来看一下,按照 DDD 分层架构模型设计出来的微服务代码模型到底长什么样子呢?

    其实,DDD 并没有给出标准的代码模型,不同的人可能会有不同理解。下面要说的这个微服务代码模型是我经过思考和实践后建立起来的,主要考虑的是微服务的边界、分层以及架构演进。

    微服务一级目录结构

    微服务一级目录是按照 DDD 分层架构的分层职责来定义的。从下面这张图中,我们可以看到,在代码模型里分别为用户接口层、应用层、领域层和基础层,建立了 interfaces、application、domain 和 infrastructure 四个一级代码目录。

    这些目录的职能是这样的。

    • Interfaces(用户接口层):它主要存放用户接口层与前端交互、展现数据相关的代码。前端应用通过这一层的接口,向应用服务获取展现所需的数据。这一层主要用来处理用户发送的 Restful 请求,解析用户输入的配置文件,并将数据传递给 Application 层。数据的组装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。
    • Application(应用层):它主要存放应用层服务组合和编排相关的代码。应用服务向下基于微服务内的领域服务或外部微服务的应用服务完成服务的编排和组合,向上为用户接口层提供各种应用数据展现支持服务。应用服务和事件等代码会放在这一层目录里。
    • Domain(领域层):它主要存放领域层核心业务逻辑相关的代码。领域层可以包含多个聚合代码包,它们共同实现领域模型的核心业务逻辑。聚合以及聚合内的实体、方法、领域服务和事件等代码会放在这一层目录里
    • Infrastructure(基础层):它主要存放基础资源服务相关的代码,为其它各层提供的通用技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。

    下面具体说明一下领域层的代码目录结构

    Domain 是由一个或多个聚合包构成,共同实现领域模型的核心业务逻辑。聚合内的代码模型是标准和统一的,包括:entity、event、repository 和 service 四个子目录。

    • Aggregate(聚合):它是聚合软件包的根目录,可以根据实际项目的聚合名称命名,比如权限聚合。在聚合内定义聚合根、实体和值对象以及领域服务之间的关系和边界。聚合内实现高内聚的业务逻辑,它的代码可以独立拆分为微服务。以聚合为单位的代码放在一个包里的主要目的是为了业务内聚,而更大的目的是为了以后微服务之间聚合的重组。聚合之间清晰的代码边界,可以让你轻松地实现以聚合为单位的微服务重组,在微服务架构演进中有着很重要的作用。
    • Entity(实体):它存放聚合根、实体、值对象以及工厂模式(Factory)相关代码。实体类采用贫血模型,同一实体相关的业务逻辑都在实体类代码中实现。跨实体的业务逻辑代码在领域服务中实现。
    • Event(事件):它存放事件实体以及与事件活动相关的业务逻辑代码。
    • Service(领域服务):它存放领域服务代码。一个领域服务是多个实体组合出来的一段业务逻辑。你可以将聚合内所有领域服务都放在一个领域服务类中,你也可以把每一个领域服务设计为一个类。如果领域服务内的业务逻辑相对复杂,我建议你将一个领域服务设计为一个领域服务类,避免由于所有领域服务代码都放在一个领域服务类中,而出现代码臃肿的问题。领域服务封装多个实体或方法后向上层提供应用服务调用。
    • Repository(仓储):它存放所在聚合的查询或持久化领域对象的代码,通常包括仓储接口和仓储实现方法。为了方便聚合的拆分和组合,我们设定了一个原则:一个聚合对应一个仓储。

    特别说明:按照 DDD 分层架构,仓储实现本应该属于基础层代码,但为了在微服务架构演进时,保证代码拆分和重组的便利性,把聚合仓储实现的代码放到了聚合包内。这样,如果需求或者设计发生变化导致聚合需要拆分或重组时,我们就可以将包括核心业务逻辑和仓储代码的聚合包整体迁移,轻松实现微服务架构演进。


    综合评价

    在这四种模型当中,失血模型和胀血模型应该是不被提倡的。而贫血模型和充血模型从技术上来说,都是可行的。但是我个人仍然主张使用贫血模型。其理由:

    • 虽然贫血模型的Domain Object确实不够rich,但Domain Object只包含属于它本身的领域逻辑,不包含持久化逻辑,将有效的隔离和屏蔽了持久化技术,进而可以对持久化技术进行灵活的替换。
    • 贫血模型中提出的按照是否依赖持久化进行划分,这种标准是非常确定的,不会引起开发团队设计上的争议。 

    展开全文
  • 本文基于公共模型设计了一种非结构化数据模型。首先文章介绍公共模型,其次说明了非结构化数据模型的设计原则、设计目标以及设计思路。通过对该模型的详细设计和实际应用,证明了遵循公共模型规范设计的非结构化数据...
  • CMMI(能力成熟度模型集成) 资料之概要设计说明书模板
  • 文档中简单记录,F28335 LED灯闪烁模型设计 附件分享如下文章: 坛友分享的,MATLAB基于模型设计(入门到精通)TMS320F28335 ,使用Adobe从结构新建书签后,分享给需要的坛友。 刘杰老师,扫描版,基于模型的设计-...
  • 智能窗帘模型设计说明 一. 实现要求 1. 自动模式:可感知光线强度,光强时控制窗帘关闭;光弱时控制窗帘打开; 2. 手动模式:可手动打开或关闭窗帘; 3. 当窗帘被完全打开到顶端时,控制器通过传感器信号反馈控制电机...
  • 在已知真实模式概率分布函数的情况下,根据要求的模型数目,等概率划分模式空间,在每个等概率模式空间上,利用方差的含义获得最大范围地覆盖模式空间的模型集,并给出一个例子说明模型集的设计方法.应用Monte-Carlo仿真,...
  • 计算机组成原理实验说明书_CPU与简单模型设计实验_西安唐都.pdf
  • 概念模型设计

    千次阅读 2010-05-04 10:36:00
    4.1.3 概念模型设计概念模型不依赖于具体的计算机系统,他是纯粹反映信息需求的概念结构。建模是在需求分析结果的基础上展开,常常要对数据进行抽象处理。常用的数据抽象方法是‘聚集’和‘概括’。ER方法是设计...
  • 计算机组成原理实验说明书_硬布线控制器模型设计实验_西安唐都.pdf
  • paper-code 对一些好的技术文章结合自己的实践经验进行翻译、举例说明等或自己的经验分享。主要包括架构设计、模式设计、模型设计、重构及源码解析等。 目录
  • 摘要 本文通过对一个“学生选课系统”示例的简要分析与设计说明UML图之一类图的两种作用及存在形式,以期借此澄清有些朋友可能对类图存在的误解与困惑。前言 在OOA与OOD大行其道的今天,UML在系统分析与设计中...
  • 领域模型设计(20190407)

    千次阅读 2019-04-07 15:50:41
    业务模型的设计无定式,领域模型设计也不是适应任何业务,对于复杂业务逻辑可考虑使用。 领域模型实践心得 领域模型与传统业务分层区别 使用Spring框架的项目,业务模型通常是: Bean-Service-Dao 其...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,261
精华内容 2,904
关键字:

模型设计说明