SAAS多租户系统的详细设计方案,后台数据库及各类框架详细设计方案-程序员必被的技术

SAAS多租户系统的详细设计方案

多租户(Multi-Tenant)架构是一种在单个软件实例中服务多个客户(租户)的设计方式。每个租户的数据和配置是独立的,但共享同一个应用程序和基础设施。设计一个高效的SAAS多租户系统需要考虑以下几个方面:架构设计、后台数据库设计、框架选择、数据隔离、安全性、可扩展性和性能优化。

1. 架构设计
1.1 多租户架构模式
  1. 单实例多租户(Single Instance, Multiple Tenants)

    • 共享数据库,独立表:所有租户共享同一个数据库,但每个租户有独立的数据表。
    • 共享数据库,共享表:所有租户共享同一个数据库和数据表,通过租户ID来区分数据。
  2. 多实例多租户(Multiple Instances, Multiple Tenants)

    • 每个租户有独立的应用实例和数据库实例。这种模式最能隔离租户,但成本较高。
1.2 基础架构
  • 负载均衡器(Load Balancer):分配用户请求到不同的应用服务器,确保系统的高可用性和性能。
  • 应用服务器(Application Server):运行SAAS应用的业务逻辑。
  • 数据库服务器(Database Server):存储和管理租户数据。
  • 缓存服务器(Cache Server):如Redis,用于缓存数据,提高访问速度。
  • 文件存储(File Storage):如Amazon S3,用于存储静态文件和用户上传的文件。
2. 后台数据库设计
2.1 数据库选择
  • 关系型数据库:如MySQL、PostgreSQL,适合结构化数据存储。
  • NoSQL数据库:如MongoDB、Cassandra,适合非结构化数据和高并发场景。
2.2 数据库模式
  1. 共享数据库,共享表

    • 表设计:所有租户的数据存储在相同的表中,通过租户ID区分。
    • 优点:资源利用率高,易于管理和维护。
    • 缺点:数据隔离性较差,安全性要求高。
    CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY,tenant_id INT,username VARCHAR(255),email VARCHAR(255),password VARCHAR(255),...INDEX (tenant_id)
    );
    
  2. 共享数据库,独立表

    • 表设计:每个租户有独立的数据表。
    • 优点:较好的数据隔离性。
    • 缺点:数据库管理复杂。
    CREATE TABLE tenant1_users (user_id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255),email VARCHAR(255),password VARCHAR(255),...
    );CREATE TABLE tenant2_users (user_id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255),email VARCHAR(255),password VARCHAR(255),...
    );
    
  3. 独立数据库

    • 每个租户有独立的数据库实例。
    • 优点:最好的数据隔离性。
    • 缺点:资源利用率低,成本高。
2.3 数据隔离
  • 逻辑隔离:通过租户ID在应用层和数据库层进行数据隔离。
  • 物理隔离:每个租户使用独立的数据库或表。
3. 框架选择
3.1 后端框架
  • Spring Boot(Java):适合构建微服务架构的企业级应用。
  • Express.js(Node.js):轻量级框架,适合快速开发。
  • Django(Python):功能全面,适合快速构建高性能Web应用。
  • Ruby on Rails(Ruby):注重开发速度和代码优雅。
3.2 前端框架
  • React:组件化的开发模式,适合构建复杂的用户界面。
  • Angular:企业级前端框架,适合大型应用开发。
  • Vue.js:轻量级框架,学习曲线较低,适合快速开发。
3.3 数据库框架

当然,我会继续详细说明SAAS多租户系统的设计方案。

  • Hibernate(Java):这是一个流行的对象关系映射(ORM)框架,简化了Java应用程序与数据库之间的交互。它支持多租户架构,可以通过不同的策略(如基于租户ID的表分区)实现数据隔离。
  • Sequelize(Node.js):这是一个基于Node.js的ORM,支持多种数据库(如MySQL、PostgreSQL、SQLite等)。它提供了模型定义和查询构建器,简化了数据库操作。
  • SQLAlchemy(Python):这是一个功能强大的Python ORM框架,支持多种数据库,适合在Django等框架中使用。它提供了灵活的查询构建和多租户支持。
  • ActiveRecord(Ruby on Rails):这是Rails内置的ORM,提供了简单而强大的数据库操作接口。它也支持多租户架构,可以通过不同的策略实现数据隔离。

4. 数据隔离和安全性

4.1 数据隔离策略
  • 基于租户ID的逻辑隔离:在共享数据库和共享表的情况下,通过在每个表中添加租户ID字段来实现数据隔离。应用程序在查询数据时需要确保所有查询都包含租户ID的过滤条件。

    SELECT * FROM users WHERE tenant_id = ?;
    
  • 基于数据库实例的物理隔离:每个租户使用独立的数据库实例。这种方法提供了最强的数据隔离,但管理和维护成本较高。

4.2 安全性措施
  • 数据加密:在传输过程中使用TLS/SSL加密来保护数据的安全性。在存储时,可以使用数据库的加密功能来保护敏感数据。
  • 访问控制:实现细粒度的权限控制,确保只有授权用户才能访问特定的租户数据。
  • 审计日志:记录所有重要操作和访问,便于审计和追踪安全事件。
  • 多因素认证(MFA):通过多因素认证来增强用户登录的安全性。

5. 可扩展性和性能优化

5.1 水平扩展
  • 服务分片:将应用服务分成多个实例,通过负载均衡器分发请求,提高系统的处理能力。
  • 数据库分片:将数据库分成多个片,每个片处理一部分租户的数据,从而减轻单个数据库实例的负载。
5.2 垂直扩展
  • 增加硬件资源:通过增加服务器的CPU、内存和存储等硬件资源来提升系统性能。
  • 优化数据库查询:通过索引、查询优化和数据库调优来提高查询性能。
5.3 性能优化技术
  • 缓存:使用缓存(如Redis、Memcached)来存储常用数据,减少数据库查询次数。
  • CDN:使用内容分发网络(CDN)来加速静态资源的加载速度。
  • 异步处理:将耗时操作(如邮件发送、文件处理)放入消息队列(如RabbitMQ、Kafka)中异步处理,提高系统响应速度。

6. 多租户支持的具体实现

6.1 租户管理
  • 租户注册:提供租户注册接口,允许新租户注册并创建相应的租户配置和数据。
  • 租户隔离:在应用程序层,通过租户ID来隔离不同租户的数据和配置。
  • 租户配置:为每个租户提供独立的配置文件,支持个性化定制。
6.2 数据访问层
  • 租户上下文:在每次请求处理时,设置当前租户的上下文信息,确保所有数据库操作都包含正确的租户ID。

  • 动态数据源:在多数据库实例的情况下,根据租户ID动态选择数据源。

    // Java示例:动态数据源选择
    public class TenantDataSourceRouting extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return TenantContext.getCurrentTenant();}
    }
    
6.3 应用程序层
  • 中间件:在应用程序中间件中提取并设置租户信息,确保在整个请求### 6. 多租户支持的具体实现,在应用程序中,通过中间件提取并设置租户信息,确保在整个请求处理过程中都能获取正确的租户上下文。

    // Java示例:Spring Boot 中的租户中间件
    @Component
    public class TenantInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String tenantId = request.getHeader("X-Tenant-ID");if (tenantId != null) {TenantContext.setCurrentTenant(tenantId);}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {TenantContext.clear();}
    }
    
  • 租户上下文管理:通过ThreadLocal或类似机制管理当前请求的租户上下文。

    // Java示例:租户上下文管理
    public class TenantContext {private static final ThreadLocal<String> currentTenant = new ThreadLocal<>();public static void setCurrentTenant(String tenantId) {currentTenant.set(tenantId);}public static String getCurrentTenant() {return currentTenant.get();}public static void clear() {currentTenant.remove();}
    }
    

7. 数据库方案

7.1 数据库表设计
  • 共享表结构:在每个表中添加租户ID字段并创建索引,以确保查询性能。

    CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,tenant_id INT,user_id INT,product_id INT,order_date DATETIME,amount DECIMAL(10, 2),INDEX (tenant_id),INDEX (tenant_id, user_id)
    );
    
  • 独立表结构:为每个租户创建独立的数据表,可以通过动态表名来实现。

    // Java示例:动态表名生成
    public class TenantTableNameProvider {public static String getUserTableName(String tenantId) {return tenantId + "_users";}
    }
    
7.2 数据库连接管理
  • 连接池:使用数据库连接池(如HikariCP)管理数据库连接,以提高连接利用率和性能。

    // Java示例:配置HikariCP连接池
    @Bean
    public DataSource dataSource() {HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");config.setUsername("user");config.setPassword("password");config.setMaximumPoolSize(10);return new HikariDataSource(config);
    }
    
  • 多数据源配置:在多实例多租户的情况下,根据租户ID动态选择数据源。

    // Java示例:多数据源配置
    @Configuration
    public class DataSourceConfig {@Beanpublic DataSource dataSource() {Map<Object, Object> dataSourceMap = new HashMap<>();dataSourceMap.put("tenant1", tenant1DataSource());dataSourceMap.put("tenant2", tenant2DataSource());TenantDataSourceRouting dataSourceRouting = new TenantDataSourceRouting();dataSourceRouting.setTargetDataSources(dataSourceMap);return dataSourceRouting;}@Beanpublic DataSource tenant1DataSource() {HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/tenant1db");config.setUsername("user1");config.setPassword("password1");return new HikariDataSource(config);}@Beanpublic DataSource tenant2DataSource() {HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/tenant2db");config.setUsername("user2");config.setPassword("password2");return new HikariDataSource(config);}
    }
    

8. 前端设计

8.1 多租户支持
  • 租户选择:在用户登录或访问时,通过URL、子域名或请求头信息获取租户ID。

    // JavaScript示例:通过子域名获取租户ID
    const tenantId = window.location.hostname.split('.')[0];
    
  • 动态配置:根据### 8. 前端设计(续)

8.1 多租户支持(续)
  • 动态配置:根据租户ID加载不同的配置和资源,如主题、语言包和功能模块。

    // JavaScript 示例:根据租户ID加载配置
    function loadTenantConfig(tenantId) {fetch(`/config/${tenantId}.json`).then(response => response.json()).then(config => {// 应用配置applyConfig(config);});
    }function applyConfig(config) {// 设置主题document.documentElement.style.setProperty('--primary-color', config.theme.primaryColor);// 设置语言setLanguage(config.language);// 加载特定功能模块loadModules(config.modules);
    }
    
  • 组件化设计:使用现代前端框架(如React、Vue.js、Angular)实现组件化设计,便于管理和复用不同租户的UI组件。

    // React 示例:租户特定的Header组件
    function TenantHeader({ tenantId }) {const [config, setConfig] = useState(null);useEffect(() => {fetch(`/config/${tenantId}.json`).then(response => response.json()).then(setConfig);}, [tenantId]);if (!config) {return <div>Loading...</div>;}return (<header style={{ backgroundColor: config.theme.primaryColor }}><h1>{config.companyName}</h1></header>);
    }
    

9. 监控和运维

9.1 监控系统
  • 应用性能监控(APM):使用APM工具(如New Relic、Datadog、Prometheus)监控应用性能,检测和分析潜在的性能瓶颈。

    # Prometheus 示例配置
    global:scrape_interval: 15sscrape_configs:- job_name: 'application'static_configs:- targets: ['localhost:9090']
    
  • 日志管理:使用集中化日志管理系统(如ELK Stack、Splunk)收集和分析日志,便于排查问题和进行安全分析。

    // Logstash 示例配置
    input {file {path => "/var/log/myapp/*.log"start_position => "beginning"}
    }output {elasticsearch {hosts => ["localhost:9200"]index => "myapp-logs-%{+YYYY.MM.dd}"}
    }
    
  • 指标监控:定义关键性能指标(KPIs),如请求响应时间、错误率、资源使用情况,并通过监控系统进行实时监控和告警。

    # Prometheus AlertManager 示例配置
    route:group_by: ['alertname']receiver: 'email'receivers:- name: 'email'email_configs:- to: 'ops@example.com'from: 'alert@example.com'smarthost: 'smtp.example.com:587'
    
9.2 自动化运维
  • 基础设施即代码(IaC):使用工具(如Terraform、Ansible)管理和部署基础设施,确保环境一致性和可重复性。

    // Terraform 示例:创建AWS EC2实例
    provider "aws" {region = "us-west-2"
    }resource "aws_instance" "app_server" {ami           = "ami-0c55b159cbfafe1f0"instance_type = "t2.micro"tags = {Name = "AppServer"}
    }
    
  • 持续集成和持续部署(CI/CD):使用CI/CD工具(如Jenkins、GitLab CI、GitHub Actions)实现自动化构建、测试和部署,确保代码质量和快速交付。

    # GitHub Actions 示例:CI/CD 工作流程
    name: CI/CDon:push:branches: [ main ]jobs:build:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: actions/checkout@v2- name: Set up Javauses: actions/setup-java@v1with:java-version: '11'- name: Build with Gradlerun: ./gradlew build- name: Deploy to AWSrun: ./deploy.sh
    

10. 常见问题和解决方案

10.1 数据一致### 10. 常见问题和解决方案
10.1 数据一致性
  • 问题:在多租户系统中,确保数据一致性和完整性非常重要,特别是在并发操作和分布式环境下。

  • 解决方案

    • 事务管理:使用数据库事务确保多个相关操作要么全部成功,要么全部失败。大多数ORM框架和数据库驱动都支持事务管理。

      // Java 示例:Spring事务管理
      @Transactional
      public void updateUserAndOrder(User user, Order order) {userRepository.save(user);orderRepository.save(order);
      }
      
    • 分布式事务:在需要跨多个服务或数据库实例的场景下,使用分布式事务管理工具(如Two-Phase Commit、Saga模式)来保证数据一致性。

      // Java 示例:Saga 模式
      @Saga
      public class OrderManagementSaga {@SagaSteppublic void createOrder(Order order) {// 创建订单逻辑}@SagaSteppublic void reserveInventory(Order order) {// 预留库存逻辑}@SagaSteppublic void confirmPayment(Order order) {// 确认支付逻辑}
      }
      
10.2 数据迁移和备份
  • 问题:随着系统的演进和租户数量的增加,数据库的结构和内容可能需要进行迁移和备份。

  • 解决方案

    • 数据库迁移工具:使用数据库迁移工具(如Flyway、Liquibase)管理数据库结构的变更。通过版本控制和自动化脚本,确保在不同环境中应用一致的数据库变更。

      # Flyway 示例配置
      flyway:url: jdbc:mysql://localhost:3306/mydbuser: userpassword: passwordlocations: classpath:db/migration
      
    • 定期备份:设置定期备份策略,使用数据库自带的备份工具或第三方工具(如AWS RDS备份、pg_dump)进行数据库备份。

      # pg_dump 示例:PostgreSQL 数据库备份
      pg_dump -U username -h localhost mydb > backup.sql
      
    • 数据恢复演练:定期进行数据恢复演练,确保在数据丢失或损坏时能够快速恢复。

10.3 多租户定制化需求
  • 问题:不同租户可能有不同的定制化需求,包括功能、UI、配置等方面。

  • 解决方案

    • 配置驱动:通过配置文件或数据库表存储租户的个性化配置,在应用启动时加载这些配置。

      // 配置示例:租户配置文件
      {"tenantId": "tenant1","theme": {"primaryColor": "#ff0000"},"features": {"featureA": true,"featureB": false}
      }
      
    • 插件架构:设计插件架构,允许租户根据需求启用或禁用特定功能模块。

      // Java 示例:Spring Boot 插件架构
      @Configuration
      public class TenantFeatureConfig {@Beanpublic FeatureManager featureManager() {FeatureManager manager = new FeatureManager();// 根据租户配置加载功能模块if (tenantConfig.isFeatureAEnabled()) {manager.enableFeature(new FeatureA());}if (tenantConfig.isFeatureBEnabled()) {manager.enableFeature(new FeatureB());}return manager;}
      }
      
10.4 性能瓶颈
  • 问题:随着租户和数据量的增加,系统可能会遇到性能瓶颈。

  • 解决方案

    • 性能监控和优化:使用APM工具和性能监控工具识别性能瓶颈,并进行针对性的优化,如数据库索引优化、代码优化等。

      -- SQL 示例:创建索引优化查询性能
      CREATE INDEX idx_orders_order_date ON orders(order_date);
      
    • 缓存:使用分布式缓存(如Redis、Memcached)缓存热点数据,减少数据库查询次数。

      // Java 示例:使用Spring Cache
      @Cacheable("orders")
      public Order getOrderById(Long orderId) {return orderRepository.findById(orderId).orElse(null);
      

多租户系统可能存在以下性能瓶颈:

  1. 资源竞争:多个租户共享服务器资源,如 CPU、内存、网络带宽等。当租户数量增多或某些租户的业务负载突然增加时,可能导致资源竞争激烈,影响系统整体性能。

  2. 数据隔离与访问控制:为了确保租户之间的数据隔离和安全性,需要复杂的访问控制机制。这可能增加数据处理的开销,特别是在大规模并发访问时。

  3. 数据库操作:大量租户同时进行数据读写操作,可能导致数据库锁竞争、查询优化困难以及索引维护成本增加。

  4. 存储优化:不同租户的数据量和访问模式可能差异很大,统一的存储策略可能无法满足所有租户的需求,导致存储效率低下。

  5. 网络延迟:如果多租户系统分布在不同的地理位置或网络环境中,网络延迟可能会影响数据传输和响应时间。

  6. 应用程序架构:不合理的系统架构可能导致模块之间的通信开销过大,影响性能。

  7. 租户定制化需求:满足租户的个性化定制需求可能引入额外的复杂性和性能开销。

  8. 备份与恢复:对多个租户的数据进行备份和恢复操作可能需要较长时间,影响系统的可用性。

  9. 监控与诊断:由于租户众多,准确监测和诊断每个租户的性能问题变得更加困难,可能导致问题发现和解决的延迟。

为了解决这些性能瓶颈,需要综合采用优化资源分配、改进数据库设计、优化应用架构、采用缓存技术、加强监控等措施。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

监控电脑的软件有哪些?精选8大监控电脑的软件

根据当前市场反馈和功能评价&#xff0c;以下是八款备受推崇的电脑监控软件推荐&#xff0c;适合不同企业和组织的监控与管理需求&#xff1a; 1.安企神监控软件 特点&#xff1a;全面的局域网监控工具&#xff0c;擅长网络设备监控、网络性能管理和故障诊断。提供员工电脑屏幕…

配置Eclipse的C++环境

配置Eclipse的C环境主要包括以下几个步骤&#xff0c;以下是详细的步骤和说明&#xff1a; 1. 下载和安装JDK&#xff08;如果尚未安装&#xff09; JDK&#xff08;Java Development Kit&#xff09;是Eclipse运行的基础&#xff0c;如果尚未安装JDK&#xff0c;请从Oracle官…

计算机网络:408考研|湖科大教书匠|原理参考模型II|学习笔记

系列目录 计算机网络总纲领 计算机网络特殊考点 计算机网络原理参考模型I 计算机网络原理参考模型II 目录 系列目录更新日志前言应用层(Application Layer)一、应用层概述二、客户/服务器方式和对等方式三、动态主机配置协议(DHCP, Dynamic Host Configuration Protocol)四、域…

最优化方法Python计算:线性规划的标准化

目标函数和约束函数均为线性函数的最优化问题 { minimize c ⊤ x s.t. A i q x ≤ b i q A e q x b e q x ≥ o ( 1 ) \begin{cases} \text{minimize}\quad\quad\boldsymbol{c}^\top\boldsymbol{x}\\ \text{s.t.\ \ }\quad\quad\boldsymbol{A}_{iq}\boldsymbol{x}\leq\bold…

微机原理与接口技术:重点内容|计算机系统|学习笔记

系列目录 前言 只将最重要的知识点考点列出来方便学习复习 目录 系列目录前言第1章 微型计算机概述第2章 16位和32位微处理机&#x1f31f;16位微处理器 8086 第3章 Pentium 的指令系统常用指令 第4章 存储器、存储管理和高速缓存技术第5章 微型计算机和外设的数据传输第6章 串…

Socket网络编程基础教程

Socket网络编程基础教程 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨Java中的Socket网络编程&#xff0c;这是实现网络通信的重要基础。 …

echarts进度环叠加背景图

vue组件实现&#xff1a; <template><div class"ringWrap" :style"{transform:scale(${scale})}"><!-- 圆环 --><div :id"chartId" :style"{width:220px,height:220px,transform:scale(${scale})}"></div…

一个适用于标准普通 WordPress 博客站点的 CloudFlare 缓存规则

长期以来很多 WordPress 站长们都以为 WordPress 这样的动态博客网站系统的 CDN 缓存效果是有限的,尤其是 WordPress 伪静态后的.html 是无法被 CDN 完美缓存的。其实这个是跟你的博客网站架构有关系,如果你的 WordPress 网站用的是单用户模式(就是只需要网站管理员登录,不…

【JavaScript】var, let, const区别

提出 var是ES5提出的&#xff0c;let和const是ES6提出的。 作用域不同 let和const具有块级作用域&#xff0c;var不存在块级作用域,可以跨块访问, 不能跨函数访问 // 全局 var a 10 console.log(a) // 10const test (c) > {var b 20console.log(b) // 20&#xff0c;…

[单master节点k8s部署]13.statefulSet

statefulSet 为每一个pod提供一个稳定的、唯一的网络标识符&#xff0c;每个 Pod 通过 PersistentVolumeClaim (PVC) 获得自己的存储。即使 Pod 被重新调度到另一个节点&#xff0c;这个 PVC 也会被重新挂载到正确的 Pod 上&#xff0c;保证存储的稳定性。 statefulset创建的p…

LeetCode-213. 打家劫舍 II【数组 动态规划】

LeetCode-213. 打家劫舍 II【数组 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;分三种情况&#xff0c;一&#xff1a;不考虑头尾&#xff1b;二&#xff1a;考虑头不考虑尾&#xff1b;三&#xff1a;考虑尾不考虑头。解题思路二&#xff1a;优化空间解题思路三&am…

Android笔记-adb keycode大全

使用方法 用adb发送按键事件时&#xff0c;可以使用下面表中的枚举值或者直接使用数值&#xff0c;比如 adb shell input keyevent KEYCODE_HOME 或者 adb shell input keyevent 3 下面按三种排序方法列出所有按键的 keycode&#xff0c; 分别是&#xff1a; 按功能分 按枚…

C++ 设计模式之命令模式

C 设计模式之命令模式 简介 1、命令模式 &#xff08;Command&#xff09;是一种行为型设计模式&#xff0c;它将一个请求封装为一个对象&#xff0c;从而使您可以用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。 2、…

浏览器userAgent大全及JS判断当前APP

文章目录 userAgent 检测PC/Mobile 浏览器 userAgent 大全Mobile APP userAgent 大全JS 判断当前 APP userAgent 检测 https://useragent.buyaocha.com/ PC/Mobile 浏览器 userAgent 大全 系统浏览器User-Agent字符串MacChromeMozilla/5.0 (Macintosh; Intel Mac OS X 10_12…

vue数组套对象,在动态加入属性:属性值, 导致数据不更新

一 、案例效果 [{a: 1,b:2},{a: 1,b:2}, toggle:true]导致视图不更新且数据没有响应式。这种格式是数组套对象的&#xff0c;之后由于不想在遍历一层数据变成[{a: 1,b:2,toggle:true},{a: 1,b:2,oggle:true} ] ,就直接加在对象后面了【虽然这样写法不对&#xff0c;但是&#…

LLM端侧部署系列 | 陈天奇MLC-LLM重磅升级:基于机器学习编译的通用LLM部署引擎

引言 简介 MLCEngine的聊天功能 OpenAI风格API 云端REST API Python API iOS SDK Android SDK WebLLM SDK 小结 结构化生成 支持各种平台 优化引擎性能 总结 引言 流星透疏水&#xff0c;走月逆行云。 小伙伴们好&#xff0c;我是《小窗幽记机器学习》的小编&am…

如何获取泛型参数【Java】

对于一个基本的类 public class BaseDao<T>{T findOne() {return T;} }它的子类 public class StudentDao extends BaseDao<StudentDao.Student>{public static class Student{}}如何获得当前类对应的泛型参数呢&#xff1f; 方法一 JDK public static void ma…

关于onlyoffice回调函数的问题

参考文档1&#xff1a;https://api.onlyoffice.com/zh/editors/callback 在官方文档中描述的十&#xff0c;文档存储服务的回调函数&#xff0c;必须要返回 {"error": 0}表示成功&#xff0c;否则将提示错误信息。 但是经过实测&#xff0c;我们只需要正常的返回2…

力扣2874.有序三元组中的最大值 II

力扣2874.有序三元组中的最大值 II 遍历j –> 找j左边最大数 和右边最大数 class Solution {public:long long maximumTripletValue(vector<int>& nums) {int n nums.size();vector<int> suf_max(n1,0);//右边最大数for(int in-1;i>1;i--){suf_max[i…

Mysql - 数据库备份和恢复

当涉及到数据库管理时&#xff0c;数据库备份和恢复是非常关键的操作。备份可以保护数据库中的重要数据免受意外删除、数据库故障或者恶意攻击的影响。同时&#xff0c;恢复操作可以帮助我们在发生意外情况时快速恢复数据库到之前的状态。在这篇文章中&#xff0c;我们将深入探…